Codeforces Round #639 (Div. 2) C Hilbert's Hotel (数学)

题目:传送门

大致题意:问是否存在两个整数 k1 和 k2  ,满足  k+ ak1%n = k2+ ak2%n 

思路: 显然,对于无穷区间我们是不能求解的,因此可以尝试着把无穷区间通过%n 运算,映射到区间 [ 0 , n -1 ] 。 

    设 k% n = i  , 则有 i + x * n = k1  ,其中 x = k1 / n  (向下取整)

      k2 %n = j   , 则有 j + y * n = k,其中 y = k/ n  (向下取整)

    k+ ak1%n = k2+ ak2%n  可化为  i + x * n + a = j + y + aj 

    对方程两边同时 %n ,得:( i + ai )% n = ( j + aj )% n ,其中 i 和 j 位于区间 [ 0 , n-1 ];

    这道题就转化为 遍历 0 ~ n-1 ,算出所有( i + ai )% n 的值并判断是否有重复 (或者判断[ 0 ,n-1 ] 中 是否有数值未出现过,有数值重复 就意味着 有其他数值空缺 )、

 1 #include<bits/stdc++.h>
 2 /*
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<vector>
 7 #include<cctype>
 8 #include<queue>
 9 #include<algorithm>
10 #include<map>
11 #include<set>
12 */
13 #pragma GCC optimize(2)
14 using namespace std;
15 typedef long long LL;
16 typedef pair<int,int> pii;
17 typedef pair<double,double> pdd;
18 const int N=2e5+5;
19 const int M=3005;
20 const int inf=0x3f3f3f3f;
21 const LL mod=1e9+7;
22 const double eps=1e-9;
23 const long double pi=acos(-1.0L);
24 #define ls (i<<1)
25 #define rs (i<<1|1)
26 #define fi first
27 #define se second
28 #define pb push_back
29 #define mk make_pair
30 #define mem(a,b) memset(a,b,sizeof(a))
31 LL read()
32 {
33     LL x=0,t=1;
34     char ch;
35     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
36     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
37     return x*t;
38 }
39 int c[N];
40 int main()
41 {
42     int T=read();
43     while(T--)
44     {
45         int n=read();
46         for(int i=0;i<n;i++)
47         {
48             int x=read();
49             c[((x+i)%n+n)%n]++;
50         }
51         int ans=0;
52         for(int i=0;i<n;i++)
53         if(c[i]==0){
54             ans=1;
55             break;
56         }
57         for(int i=0;i<n;i++) c[i]=0;
58         if(ans) printf("NO
");
59         else printf("YES
");
60     }
61     return 0;
62 }
View Code

    

原文地址:https://www.cnblogs.com/DeepJay/p/12861148.html