不得不说,这不是一道好题,很烂...逻辑复杂,需要非常周全精细的考虑,需要避免的坑有很多。这种类似排队的模拟题,目前为止这是第三道(1014,1017,1026),有着大体相似的描述和思路(我回去看了看之前的记录,发现这种类型的题真的很让我头疼,我太菜了),但这题由于加了个vip制度,使得代码量剧增。可以看到通过的代码十分冗长(当然也有我自己的原因,太菜了)。约两百行的代码。第一次提交的时候得了25分,测试点5,7,8没过,原来是我漏考虑了一种情况,就是说当有多个vip桌子空出来时,选择vip桌号最小的而不是普通桌号最小的,大概是这个意思。如果能通过一下测试用例,测试点5应该就能通过:
测试用例: 4 06:00:00 30 1 08:00:00 30 1 10:00:00 30 1 12:00:00 30 1 5 1 3 输出应为: 06:00:00 08:00:00 120 08:00:00 08:00:00 0 10:00:00 10:00:00 0 12:00:00 12:00:00 0 1 0 3 0 0
我参考了别人的博客(主要看了别人的文字描述,代码真的看不下去,都太长了),想着为桌子选人可能会有漏洞,后来想重新换一个策略是,为人找桌子,不知道哪里出错了,死活跳不出循环,我又太垃圾了不会用dev进行调试,干脆放弃,在原来25分的代码基础上进行修补,然后修补了这一点得了26分...合着用了这么长时间才多拿了一分...还剩下测试点7,8。后来又试着用dev的单步调试功能,发现我一直以为出bug的部分其实没有错,错在另一部分,佛了...然后很快找到了其中的疏漏,其实我思路没有错,只是变量设置的太多了,写着写着甚至忘记了某标志的功能,应该为该标志添加判断的地方没有添加(代码中的label)。如果能通过一下测试用例,应该能通过测试点7和8:
测试用例为: 3 07:59:31 60 1 07:59:29 60 1 08:00:30 100 1 2 1 1 输出为: 1 07:59:29 08:00:00 1 07:59:31 08:00:00 0 08:00:30 09:00:00 60 2 1
虽然题目说了保证到达时间在八点到晚上九点之间,但如过代码能按照上述的测试输出一样的结果,应该就没问题了(反正我是这样的)。我的代码其实可以精简一点,变量名可以改改,可读性会更强,但我觉得这题实在没有过多的学习价值,反复的在一些题目没有明确说明的要求里设置坑点,这是pat题目的特点...有时间再补充写写思路,免得以后看自己的代码都看不懂了
1 #include <iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 struct player{ 8 int arrive,serve,wait,vip,P,visited; 9 player(){ 10 arrive=serve=wait=vip=P=visited=0; 11 } 12 }; 13 struct table{ 14 int vip,finish,cnt; 15 table(){ 16 vip=cnt=0; 17 finish=28800; 18 } 19 }; 20 bool cmp0(player a,player b){ 21 return a.arrive<b.arrive; 22 } 23 bool cmp1(player a,player b){ 24 return a.serve<b.serve; 25 } 26 int main() 27 { 28 int N,hh,mm,ss,P,vip,arrive; 29 scanf("%d",&N); 30 vector<player> Ordinary,Vip; 31 player PLAY; 32 int cnt2=0; 33 for(int i=0;i<N;i++){ 34 scanf("%d:%d:%d%d%d",&hh,&mm,&ss,&P,&PLAY.vip); 35 PLAY.arrive=hh*3600+mm*60+ss; 36 if(PLAY.arrive) 37 if(P*60<7200) 38 PLAY.P=P*60; 39 else 40 PLAY.P=7200; 41 if(PLAY.vip==1) 42 cnt2++; 43 44 Ordinary.push_back(PLAY); 45 } 46 sort(Ordinary.begin(),Ordinary.end(),cmp0); 47 int K,M,m; 48 scanf("%d%d",&K,&M); 49 vector<table> T(K+1);//vip桌信息 50 for(int i=0;i<M;i++) { 51 scanf("%d",&m); 52 T[m].vip=1; 53 } 54 int min,mintable; 55 vector<player> res; 56 int flag=0,cnt1=0; 57 while(cnt1<N&&flag==0){ 58 if(Ordinary[cnt1].visited==1){ 59 cnt1++; 60 continue; 61 } 62 int flag1=0; 63 if(Ordinary[cnt1].vip==1){ 64 for(int i=1;i<=K;i++){ 65 if(T[i].finish<=Ordinary[cnt1].arrive&&T[i].vip==1){ 66 mintable=i; 67 flag1=1; 68 69 break; 70 } 71 } 72 if(flag1==0){ 73 for(int i=1;i<=K;i++){ 74 if(T[i].finish<=Ordinary[cnt1].arrive){ 75 mintable=i; 76 flag1=1; 77 break; 78 } 79 } 80 } 81 if(flag1==0){ 82 min=T[1].finish;//找到结束时间最早的桌子 83 mintable=1; 84 flag1=1; 85 for(int p=2;p<=K;p++){ 86 if(T[p].finish<min){ 87 min=T[p].finish; 88 mintable=p; 89 } 90 } 91 } 92 93 } 94 else{ 95 if(flag1==0){ 96 for(int i=1;i<=K;i++){ 97 if(T[i].finish<=Ordinary[cnt1].arrive){ 98 mintable=i; 99 flag1=1; 100 break; 101 } 102 } 103 } 104 if(flag1==0){ 105 min=T[1].finish;//找到结束时间最早的桌子 106 mintable=1; 107 for(int p=2;p<=K;p++){ 108 if(T[p].finish<min){ 109 min=T[p].finish; 110 mintable=p; 111 } 112 } 113 } 114 } 115 int label=0; 116 if(T[mintable].vip==1&&cnt2!=0){ 117 for(int j=cnt1;j<Ordinary.size();j++){//在队伍中找到第一个满足一下条件的vip 118 if(Ordinary[j].vip==1&&Ordinary[j].visited==0&&Ordinary[j].arrive<=T[mintable].finish&&label==0) 119 { label=1; 120 Ordinary[j].wait=T[mintable].finish-Ordinary[j].arrive; 121 Ordinary[j].serve=T[mintable].finish;//记录被服务的时间 122 123 T[mintable].finish+=Ordinary[j].P; 124 Ordinary[j].visited=1; 125 cnt2--; 126 if(Ordinary[j].serve>=75600) 127 { flag=1; 128 break; 129 } 130 res.push_back( Ordinary[j]); 131 T[mintable].cnt++; 132 if(j==cnt1) 133 cnt1++; 134 } 135 } 136 137 if(label!=1){ 138 if(Ordinary[cnt1].visited==0){ 139 if(T[mintable].finish>Ordinary[cnt1].arrive) { 140 Ordinary[cnt1].wait=T[mintable].finish-Ordinary[cnt1].arrive; 141 Ordinary[cnt1].serve=T[mintable].finish;//记录被服务的时间 142 T[mintable].finish+=Ordinary[cnt1].P; 143 } 144 else 145 { Ordinary[cnt1].serve=Ordinary[cnt1].arrive;//记录被服务的时间 146 T[mintable].finish=Ordinary[cnt1].arrive+Ordinary[cnt1].P; 147 } 148 Ordinary[cnt1].visited=1; 149 if(Ordinary[cnt1].serve>=75600) 150 { flag=1; 151 break; 152 } 153 res.push_back( Ordinary[cnt1]); 154 T[mintable].cnt++; 155 156 } 157 cnt1++; 158 } 159 } 160 else//如果不是vip桌 ,选出未被服务的队首 161 { 162 if(Ordinary[cnt1].visited==0){ 163 if(T[mintable].finish>Ordinary[cnt1].arrive) { 164 Ordinary[cnt1].wait=T[mintable].finish-Ordinary[cnt1].arrive; 165 Ordinary[cnt1].serve=T[mintable].finish;//记录被服务的时间 166 T[mintable].finish+=Ordinary[cnt1].P; 167 } 168 else 169 { Ordinary[cnt1].serve=Ordinary[cnt1].arrive;//记录被服务的时间 170 T[mintable].finish=Ordinary[cnt1].arrive+Ordinary[cnt1].P; 171 } 172 Ordinary[cnt1].visited=1; 173 if(Ordinary[cnt1].serve>=75600) 174 { flag=1; 175 break; 176 } 177 res.push_back( Ordinary[cnt1]); 178 T[mintable].cnt++; 179 180 } 181 cnt1++; 182 } 183 184 } 185 sort(res.begin(),res.end(),cmp1); 186 int temp1,temp2,temp3,temp4,temp5,temp6; 187 for(int i=0;i<res.size();i++){ 188 temp1=res[i].arrive/3600; 189 temp2=(res[i].arrive-temp1*3600)/60; 190 temp3=(res[i].arrive-temp1*3600-temp2*60); 191 temp4=res[i].serve/3600; 192 temp5=(res[i].serve-temp4*3600)/60; 193 temp6=(res[i].serve-temp4*3600-temp5*60); 194 double temp7=res[i].wait/60.0; 195 printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n",temp1,temp2,temp3,temp4,temp5,temp6,round(temp7)); 196 } 197 for(int i=1;i<=K;i++){ 198 if(i!=K) 199 printf("%d ",T[i].cnt); 200 else 201 printf("%d",T[i].cnt); 202 } 203 return 0; 204 }
原文:https://www.cnblogs.com/wsshub/p/12556493.html