kick start 2019 round D T2题解

  题目大意:由N个房子围成一个环,G个人分别顺时针/逆时针在房子上走,一共走M分钟,每分钟结束,每个人顺/逆时针走到相邻的房子。对于每个房子都会记录最后时刻到达的人(可能是一群人)。最终输出每个人会被几个房子记录。

  数据范围:N<=1e5,G<=1e5,M<=1e9,多组测试数据。

  解题思路:比赛时没做出来第二个测试点,有点失了智。。。看了下题解马上就有了想法。关键点在于①将顺时针逆时针分开考虑②从走过M步的最终状态向前思考③从单个人变成一群人代码的准确性④代码的准确性。
  我的想法是:先将顺时针单独考虑,然后得到最终状态,对于N个屋子进行逆时针循环(由于从最终状态倒退),若该房子有一群人,则记录此编号,并刷新时间戳(M),若该房子没有人,则根据时间戳标记之前记录的编号。对逆时针进行同样的操作。最终统一看,对于每一个房子:顺逆时针时间戳不同则将较大的人群num++,相同则都num++。最终输出即可。
  由于我的stl还不熟练,完全的C风格让代码较为复杂,但真的是一个好题,做得很慢,估计写了45min吧。

  最终代码:

  1 #include <stdio.h>
  2 
  3 using namespace std;
  4 
  5 int st[100010];
  6 int clock[100010];
  7 int lis[100010];
  8 int gcst[100010],gast[100010],gcfi[100010],gafi[100010];
  9 int gcnum[100010],ganum[100010];
 10 int tima[100010],timc[100010],lasa[100010],lasc[100010];
 11 int flag[100010];
 12 
 13 int mainn()
 14 {
 15     int n,g,m;scanf("%d%d%d",&n,&g,&m);
 16     for (int i=0;i<g;i++)
 17     {
 18         scanf("%d",&st[i]);
 19         char ch=getchar();while (ch==' ') ch=getchar();
 20         if (ch=='A') clock[i]=-1;else clock[i]=1;
 21     }
 22     int ngc=0,nga=0;
 23     for (int i=0;i<=n;i++) flag[i]=-1;
 24     for (int i=0;i<g;i++)
 25     if (clock[i]>0){
 26         if (flag[st[i]]==-1){
 27             flag[st[i]]=ngc;gcst[ngc]=st[i];lis[i]=ngc++;
 28         }
 29         else
 30             lis[i]=flag[st[i]];
 31     }
 32 
 33     for (int i=0;i<=n;i++) flag[i]=-1;
 34     for (int i=0;i<g;i++)
 35     if (clock[i]<0){
 36         if (flag[st[i]]==-1){
 37             flag[st[i]]=nga;gast[nga]=st[i];lis[i]=nga++;
 38         }
 39         else
 40             lis[i]=flag[st[i]];
 41     }
 42 
 43     for (int i=0;i<ngc;i++) gcfi[i]= (gcst[i]-1+m)%n+1;
 44     for (int i=0;i<nga;i++) gafi[i]= ((gast[i]-1-m)%n+n)%n+1;
 45 
 46     for (int i=0;i<ngc;i++) gcnum[i]=0;
 47     for (int i=0;i<nga;i++) ganum[i]=0;
 48 
 49     for (int i=0;i<=n;i++) lasa[i]=lasc[i]=tima[i]=timc[i]=-1;
 50 
 51     int tmp=0,fin=0;
 52     for (int i=0;i<ngc;i++){
 53         if (tmp==0) tmp=fin=gcfi[i];
 54         lasc[ gcfi[i] ]=i;timc[ gcfi[i] ]=m;
 55     }
 56 
 57     int last=lasc[tmp];int _time=m;tmp=tmp-1;if (tmp==0) tmp=n;
 58     while(fin>0 && tmp!=fin){
 59         _time--;
 60         if ( lasc[tmp]==-1 && _time>=0 )
 61             lasc[tmp]=last,timc[tmp]=_time;
 62         else if ( lasc[tmp]!=-1 )
 63             last=lasc[tmp],_time=m;
 64         tmp--;if (tmp==0) tmp=n;
 65     }
 66 
 67     tmp=fin=0;
 68     for (int i=0;i<nga;i++){
 69         if (tmp==0) tmp=fin=gafi[i];
 70         lasa[gafi[i]]=i;tima[ gafi[i] ]=m;
 71     }
 72     last=lasa[tmp];_time=m;tmp=tmp%n+1;
 73     while (fin>0 && tmp!=fin){
 74         _time--;
 75         if ( lasa[tmp]==-1 && _time>=0 )
 76             lasa[tmp]=last,tima[tmp]=_time;
 77         else if ( lasa[tmp]!=-1 )
 78             last=lasa[tmp],_time=m;
 79         tmp=tmp%n+1;
 80     }
 81 
 82     for (int i=0;i<ngc;i++) gcnum[i]=0;
 83     for (int i=0;i<nga;i++) ganum[i]=0;
 84 
 85     for (int i=1;i<=n;i++)
 86     {
 87         if (lasa[i]>=0 && lasc[i]>=0){
 88             if ( tima[i]>timc[i] )
 89                 ganum[ lasa[i] ]++;
 90             else if (tima[i]<timc[i])
 91                 gcnum[ lasc[i] ]++;
 92             else
 93                 ganum[ lasa[i] ]++,gcnum[ lasc[i] ]++;
 94         }
 95         else if (lasa[i]>=0){
 96             ganum[ lasa[i] ]++;
 97         }
 98         else if (lasc[i]>=0){
 99             gcnum[ lasc[i] ]++;
100         }
101     }
102     /*
103     printf("\n\n");
104     for (int i=1;i<=n;i++)
105         printf("%d ",lasc[i]);
106     printf("\n");
107     for (int i=1;i<=n;i++)
108         printf("%d ",timc[i]);
109     printf("\n");
110     for (int i=1;i<=n;i++)
111         printf("%d ",lasa[i]);
112     printf("\n");
113     for (int i=1;i<=n;i++)
114         printf("%d ",tima[i]);*/
115     for (int i=0;i<g;i++)
116     {
117         if(clock[i]>0)
118             printf(" %d",gcnum[lis[i]]);
119         else
120             printf(" %d",ganum[lis[i]]);
121     }
122     printf("\n");
123 
124 }
125 
126 
127 
128 int main()
129 {
130     int T;scanf("%d",&T);
131     for (int i=1;i<=T;i++)
132     {
133         printf("Case #%d:",i);
134         mainn();
135     }
136 }
View Code

  好题,值得重新练习的“模拟题”。

  题目链接:https://codingcompetitions.withgoogle.com/kickstart/round/0000000000051061/0000000000161427

posted on 2019-08-11 17:31  askl123  阅读(238)  评论(0)    收藏  举报

导航