C. Hilbert’s Hotel(数论&思维)

题目传送门

思路:因为要每个客人要安排到不同的房间,所以首先对

∀ i , j , 0 < i < j < n , ( t o i = i + a i ) ≠ ( t o j = j + a j ) \forall i,j,0<i<j<n,(to_i=i+a_i)\neq (to_j=j+a_j) i,j,0<i<j<n,(toi=i+ai)=(toj=j+aj).

又因为:对于 j = k n + i , ( k = 1 , 2 , 3 …   ) j=kn+i,(k=1,2,3\dots) j=kn+i,(k=1,2,3) t o j = k n × t o i to_j=kn\times to_i toj=kn×toi

所以还要保证对 ∀ i , j , 0 < i < j < n \forall i,j,0<i<j<n i,j,0<i<j<n t o i   m o d   n ≠ t o j   m o d   n to_i\bmod n\neq to_j\bmod n toimodn=tojmodn.

所以我们将所有 t o i to_i toi限定在范围 [ 0 , n − 1 ] [0,n-1] [0,n1]的范围内,最后只需判断一下是否集合中有 n n n个数即可。注意负数要 + n +n +n后再取模.

AC代码:

#include<cstdio>
#include<set>
using namespace std;
int main(){
	int n,t;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		set<int>s;
		for(int i=0,x;i<n;i++){
			scanf("%d",&x);
			s.insert(((x+i)%n+n)%n);
		}//n个数,且这n个数不能相同. 
		puts(s.size()==n?"YES":"NO");
	}
	return 0;
}