zoukankan      html  css  js  c++  java
  • D. Game of Pairs (构造,思维)

    题目:传送门

    题意

    有两个人 First 和 Second 在玩游戏,首先,给出一个 n,First 会将 1,2,....2*n 这 2*n 个数分成 n 组,而 Second 要在这 n 组数中,每组选一个数,若 Second 选的 n 个数的和是 2 * n 的倍数,则 Second 赢,否则,Frist 赢。

    现在给你一个 n,问你你是要选 First 还是选 Second;

    若你选 First,那你需要输出一个长度为 2*n 的序列, ans[ i ] 表示 i 这个数属于哪个组,且你的分组必须使得 Second 不能赢。

    若你选 Second,那会输入一个 2 * n 的序列,表示 First 的分组,你需要输出 n 个不同组的数,表示你选则的数,且这些数的和必须是 2 * n 的倍数。

    1 <= n <= 5e5

    思路

    精彩讲解

    首先,这题需要分两种情况考虑

    1.若 n 是偶数,则选先手必胜

    此时可以让 (i, i + n) 一组,这样,Second 选择的 n 个数,取余 n 分别等于 1, 2, 3, .. n - 1,那么他们的总和就是 s = n * (n - 1) / 2,设 n = 2 * m, 则 s = m * (2 * m - 1),由于 2 * m - 1 是奇数,所以,s 不可能是 n 的倍数,就更加不可能是 2n 的倍数了。

    2.若 n 是奇数,则后手必胜

    结论1:首先,若可以选择出 n 个数,使得它们的和是 n 的倍数,则一定存在一种策略,选择出 n 个数,使得它们的和是 2n 的倍数,此时它们的和在 mod n 意义下就是 0 + 1 + 2 +... + (n - 1) = n * (n - 1) / 2,一定是 n 的倍数。

    证:

    首先, 1 + 2 + ... + 2*n = 2*n * (2*n + 1) / 2 = n * (2 * n + 1),所以 n * (2 * n + 1) % (2 * n) = n,也就是所有数的和 % 2n = n。

    那如果我们选择出的 n 个数的和 % 2n = n,那其他的 n 个数的和 % 2n 就会等于 0,所以无论如何,一定可以选出 n 个数,使得它们的和 % 2n = 0;

    结论2:一定存在一种方案,使得 mod n = 0, 1, 2 .... n - 1 的数各被选中一次

    证:

    先随便选一个mod n = 0 的数(也就是或 2n)。假设与它配对的数 mod x。再选另一个mod 的数。再把与新选的数配对的数抛弃掉,选一个与之同余的......。直到某一次被抛弃掉的数,就是另一个 modn = 0 的数,那么当前所选的数就形成了一个闭环。同理,剩下的数也一定是若干个闭环,每个环相互独立,我们各个击破即可。

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    int n, x, vis[N], pre[N];
    
    vector < int > G[N];
    
    vector < int > Q[2];
    
    void dfs(int u, int x) {
    
        Q[x].pb(u);  vis[u] = 1;
    
        for(auto v : G[u]) if(!vis[v]) dfs(v, x ^ 1);
    
    }
    
    void solve() {
    
        cin >> n;
    
        if(n % 2 == 0) {
    
            cout << "First" << endl;
    
            rep(i, 0, (2 * n) - 1) {
                
                cout << (i % n) + 1 << " ";
    
            }
            
            cout << endl;
            
            cin >> x;
    
            return ;
    
        }
    
        cout << "Second" << endl;
    
        rep(i, 1, 2 * n) {
    
            cin >> x;
    
            if(!pre[x]) pre[x] = i;
    
            else G[pre[x]].pb(i), G[i].pb(pre[x]);
    
        }
    
        rep(i, 1, n) G[i].pb(i + n), G[i + n].pb(i);
    
        rep(i, 1, 2 * n) if(!vis[i]) dfs(i, 0);
    
        LL s = 0;
    
        for(auto v : Q[0]) s += v;
    
        if(s % (2 * n) == 0) {
    
            for(auto v : Q[0]) cout << v << " ";
    
        }
    
        else for(auto v : Q[1]) cout << v << " ";
    
        cout << endl;
    
        cin >> x;
    
    }
    
    
    int main() {
    
    //    int _; scanf("%d", &_);
    //    while(_--) solve();
    
        solve();
    
        return 0;
    }
  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/Willems/p/13646487.html
Copyright © 2011-2022 走看看