标签:
聪明的你一定知道答案!
Hint1:如果 n=6,k=2,位置变化为:1 -> 3 -> 5 -> 5 -> 3 -> 1 -> 3 -> 5 .... 显然,此时不能将所有格子打上标记。(如下图)
6 2 6 3
NO YES
无
2015苏州大学ACM-ICPC集训队选拔赛(1)
此题在上学期做过,当时比较naive也是想模拟思路是到头了用reverse数组反转过来再走,然后就机智地TLE了。突然想回来做做这题,当然还是模拟,思路是到头了继续走至超出范围,然后将当前pos对称回来,有种折叠的感觉...事实证明方法可行,但是一交TLE,10W的循环量怎么会TLE?然后找半天找到了几组数据:4 99999,类似于这种k很大n很小的情况下。while里面的while会循环巨多次,此时估计数据量上千万甚至更高然后咋办呢,就开一个结构体数组记录这个点向左走和向右走时是否经过这个点。假设一个点向左走次数或向右走的次数大于等于2,那么这个点在对应的方向被经过了至少两次,可以判断这组数据是走不出来的——只有走不出来的数组才会在某个点重复走来走去。否则让它循环完。
最后膜拜一下那个0ms代码长度还只有300+的。估计是数学方法吧,吾等智商不够又懒...强行模拟好了
代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; typedef long long LL; #define INF 0x3f3f3f3f struct info { int a; int b; }; info pos[100010]; int main(void) { int n,k,i,res; while (~scanf("%d%d",&n,&k)) { memset(pos,0,sizeof(pos)); if(k==1||n==1)//特判 { puts("YES"); continue; } int moni=0;//模拟循环量 bool flag=0; int chushi=1;/初始位置 int cheng=1;//向左/右走 int cnt=0;//走过的路个数(不重复) while (moni<=100010) { chushi+=cheng*k; while(chushi>n||chushi<1) { if(chushi>n) { cheng=-1; chushi=n-(chushi-n); } if(chushi<1) { cheng=1; chushi=2-chushi; } } if(pos[chushi].a>=2||pos[chushi].b>=2)//重复走过,标记后break { flag=0; break; } if(cheng==1)//继续正着走 { if(pos[chushi].a==0) { cnt++; } pos[chushi].a++; } else//反着走 { if(pos[chushi].b==0) { cnt++; } pos[chushi].b++; } if(cnt==n)//模拟量到达,break { flag=1; break; } moni++; } if(flag) { puts("YES"); } else { puts("NO"); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/Blackops/p/5443918.html