CF1344A Hilbert‘s Hotel题解

CF1344A Hilbert’s Hotel

题意:有一个房间编号到无穷大的旅馆(有0有负),每个房间都有一个客人,有一个位移量a数组,需要重新安排客人,新的规则就是把在 k k k房间的客人转移到 k + a k % n k+a_{k\%n} k+ak%n房间,问最后是不是每个房间都不超过1个客人。
解法:下面的推导中, k 1   k 5 k_1~k_5 k1 k5都是一整数。题目的意思就是要是否存在两个整数 k 1 , k 2 k_1,k_2 k1,k2满足 k 1 + a k 1 % n = k 2 + a k 2 % n k_1+a_{k_1\%n}=k_2+a_{k_2\%n} k1+ak1%n=k2+ak2%n这个式子的。开始化简公式:
k 1 + a k 1 % n = k 2 + a k 2 % n k_1+a_{k_1\%n}=k_2+a_{k_2\%n} k1+ak1%n=k2+ak2%n
s = k 1 % n , t = k 2 % n s=k_1\%n, t=k_2\%n s=k1%n,t=k2%n,则 k 1 = k 3 ∗ n + s , k 2 = k 4 ∗ n + t k_1=k_3*n+s,k_2=k_4*n+t k1=k3n+s,k2=k4n+t
代入得: k 3 ∗ n + s + a s = k 4 ∗ n + t + a t k_3*n+s+a_s=k_4*n+t+a_t k3n+s+as=k4n+t+at
n ∗ ( k 3 − k 4 ) + s + a s = t + a t n*(k_3-k_4)+s+a_s=t+a_t n(k3k4)+s+as=t+at
k 5 = k 3 − k 4 , a s = s + a s , a t = t + a t k_5=k_3-k_4,a_s=s+a_s,a_t=t+a_t k5=k3k4,as=s+as,at=t+at
n ∗ k 5 + a s = a t n*k_5+a_s=a_t nk5+as=at
对两边模 n n n,则是 a s % n = a t % n a_s\%n=a_t\%n as%n=at%n
也就是说,就是判断这个式子是否成立 ( a i + i ) % n = ( a j + j ) % n (a_i+i)\%n=(a_j+j)\%n (ai+i)%n=(aj+j)%n,如果是,则会有一个房间有两个客人,若不是,则不会。
代码

#include  <algorithm>
#include  <iostream>
#include  <cstring>
#include  <vector>
#include  <cstdio>
#include  <queue>
#include  <cmath>
#include  <set>
#include  <map>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define _for(n,m,i) for (register int i = (n); i < (m); ++i)
#define _rep(n,m,i) for (register int i = (n); i <= (m); ++i)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define PI acos(-1)
#define eps 1e-8
#define rint register int
#define F(x) ((x)/3+((x)%3==1?0:tb))
#define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<double, int> pdi;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<int, int> mii;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
    
    
  int f = 1; res = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    
     if(c == '-') f = -1; c = getchar(); }
  while(c >= '0' && c <= '9') {
    
     res = res * 10 + c - '0'; c = getchar(); }
  res *= f;
}
const int ne[8][2] = {
    
    1, 0, -1, 0, 0, 1, 0, -1, -1, -1, -1, 1, 1, -1, 1, 1};
const int INF = 0x3f3f3f3f;
const int N = 2e5+10;
const LL Mod = 1e9+7;
const int M = 1e6+10;
int a[N];
mii m;
int main() {
    
    
  int T; scanf("%d", &T);
  int n, x;
  while(T--) {
    
    
    memset(a, 0, sizeof a);
    scanf("%d", &n);
    int f = 1, mid;
    _for(0, n, i) {
    
    
      scanf("%d", &x);
      mid = ((x + i) % n + n) % n;
      if(a[mid]) f = 0;
      ++a[mid];
    }
    if(f) puts("YES");
    else puts("NO");
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43408978/article/details/108889203