[codeforces 1345C] Hilbert's Hotel 找规律+周期+转圈圈(模)

我的梦境 提交于 2020-05-08 15:26:45

Codeforces Round #639 (Div. 2)   5月3日,正要开打前5分钟,来了句Codeforces Round #639: the round is rescheduled,5月6日开打,遇到了测试要排长长的队伍(印象中IOI比赛是这样),抓狂,唯一慰藉的是,此场Unrated。   比赛人数13765

[codeforces 1345C]   Hilbert's Hotel   找规律+周期+转圈圈(模)

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1345/problem/C

Problem Lang Verdict Time Memory
C - Hilbert's Hotel GNU C++17 Accepted 77 ms 5200 KB

样例模拟如下

Input:
6
1
14
2
1 -1
4
5 5 5 1
3
3 2 1
2
0 1
5
-239 -2 -100 -3 -11
Output:
YES
YES
YES
NO
NO
YES

1
14
YES

初始情况-3,-2,-1,0,1,2,3
移动情况(-3+14=11),(-2+14=12),(-1+14=13),(0+14=14),(1+14=15),(2+14=16),(3+14=17)
可以看出,周期是1

2
1 -1
YES

初始情况            -4,-3,-2,-1,0,1,2,3
移动情况            (-4+1=-3,-3-1=-4),(-2+1=-1,-1-1=-2),(0+1=1,1-1=0),(2+1=3,3-1=2)
可以看出,周期是2,考虑将移动情况模周期
((-3%2+2)%2=1,(-4%2+2)%2=0),((-1%2+2)%2=1,(-2%2+2)%2=0),(0+1=1,1-1=0),(3%2=1,2%2=0)
这样每个周期的情况就完全一致了。

4
5 5 5 1
YES

初始情况            -4,-3,-2,-1,0,1,2,3
移动情况            (-4+5=1,-3+5=2,-2+5=3,-1+1=0),(0+5=5,1+5=6,2+5=7,3+1=4)
可以看出,周期是4,考虑将移动情况模周期
(-4+5=1,-3+5=2,-2+5=3,-1+1=0),(5%4=1,6%4=2,7%4=3,4%4=0)
这样每个周期的情况就完全一致了。

3
3 2 1
NO
初始情况            -3,-2,-1,0,1,2
移动情况            (-3+3=0,-2+2=0,-1+1=0),(0+3=3,1+2=3,2+1=3)
可以看出,周期是3,在发生冲突的时候,每个周期的冲突情况都是一致的。
考虑将移动情况模周期(-3+3=0,-2+2=0,-1+1=0),((0+3)%3=0,(1+2)%3=0,(2+1)%3=0)
这样每个周期的冲突情况就完全一致了。

2
0 1
NO
初始情况            -2,-1,0,1
移动情况            (-2+0=-2,-1+1=0),(0+0=0,1+1=2)
可以看出,周期是2,在发生冲突的时候,每个周期的冲突情况都是一致的。
考虑将移动情况模周期(((-2+0)%2+2)%2=0,-1+1=0),(0+0=0,(1+1)%2=0)
这样每个周期的冲突情况就完全一致了。

5
-239 -2 -100 -3 -11
初始情况-5,-4,-3,-2,-1,0,1,2,3,4
移动情况(-5-239=-244,-4-2=-6,-3-100=-103,-2-3=-5,-1-11=-12),
(0-239=-239,1-2=-1,2-100=-98,3-3=0,4-11=-7)
可以看出,周期是5,考虑将移动情况模周期
((-244%5+5)%5=1,(-6%5+5)%5=4,(-103%5+5)%5=2,(-5%5+5)%5=0,(-12%5+5)=3),
((-239%5+5)%5=1,(-1%5+5)%5=4,(-98%5+5)%5=2,0,(-7%5+5)=3)
这样每个周期的情况就完全一致了。

AC代码如下

#include <cstdio>
#include <algorithm>
#define maxn 200010
using namespace std;
int a[maxn],b[maxn];
int main(){
	int t,n,i,flag;
	scanf("%d",&t);
	while(t--){
		flag=0;
		scanf("%d",&n);
		for(i=0;i<n;i++)scanf("%d",&a[i]);
		for(i=0;i<n;i++)b[i]=0;
		for(i=0;i<n;i++)b[((i+a[i])%n+n)%n]++;
		for(i=0;i<n;i++)
			if(b[i]>1){flag=1;break;}
		if(flag)printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!