码迷,mamicode.com
首页 > 其他好文 > 详细

NOJ——1624死胡同(胡搞模拟)

时间:2016-04-28 20:07:57      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

  • [1624] 死胡同

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • 一个死胡同由排成一列的 n 个格子组成,编号从 1 到 n 。
    实验室的“猪猪”一开始在1号格子,开始向前走,每步一格,并且每走 k 步会在当前的格子上打上记号(开始时,1号格子也有记号)。由于这是死胡同,每当“猪猪”走到最左或者最右的格子时,它会改变方向。好奇的“猪猪”在想:如果我一直走,能否把所有格子都打上记号呢?

    聪明的你一定知道答案!

    Hint1:如果 n=6,k=2,位置变化为:1 -> 3 -> 5 -> 5 -> 3 -> 1 -> 3 -> 5 .... 显然,此时不能将所有格子打上标记。(如下图)

    技术分享

  • 输入
  • 多组输入数据(组数<=100)
    每组数据一行,包含两个正整数 n 和 k。
    (1 <= n <= 100000 , 1 <= k <= 100000)
  • 输出
  • 对于每组数据输出一行 YES 或者 NO 代表能否给所有格子打上标记。
  • 样例输入
  • 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;
}

 

  

 

NOJ——1624死胡同(胡搞模拟)

标签:

原文地址:http://www.cnblogs.com/Blackops/p/5443918.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!