思路:因为要每个客人要安排到不同的房间,所以首先对
∀ 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,n−1]的范围内,最后只需判断一下是否集合中有 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;
}