「インスパカップ」シャンドン第7回ACMTribleNim

トピックリンク

TribleNim

回答

題名

石の山を3つの部分に分割するNimゲーム。最初に倒す必要のある組み合わせの数を見つけます。

アイデア

まずこの結論を知る必要があります。a⨁b⨁c= = 0 a \ bigoplus b \ bigoplus c == 0abc==0上部手を失った場合に、前記abc各スタックのための石の数。

次に、状況について説明します。

石の総​​数が奇数の場合、XORの合計を計算する方法はありません0奇数を3つの整数に分割する場合、ビットの排他的ORを作成する奇数が少なくとも1つ存在する必要があります1

石の総​​数が偶数の場合、石の3つの山のXOR合計を、0にするため1に、2桁の各中央値の桁数を2またはにする必要があり0ます。
この方法でのみ、最終的なXORと合計のすべてのビットを等しくすることができます0
例えば:

14 = 1110 = 1000 + 100 + 10;
ここで、1000 = 0000 + 0100 + 0100、100 = 000 + 010 + 010、10 = 00 + 01 +01。

各ビットはどこで見ることができる1数の三二つに分割さを持っている1し、10これらの3つの数字が3つの配列を持つことができるため、: 、011私たちの答えはあるので^ N 3 N 3101110
3N

本当に?質問の意味を考えてみましょう。各山の石の数を同じにすることはできず0[1,2,3]合計[1,3,2]は同じケースとしてカウントされるため、これら2つのケースの数を差し引く必要があります。

まず、石0数がである場合を考えてみましょう。それぞれを分割しているので1、3つの場合があり、そのうちの1ビットのみであり、最大0で1つの石の山しかありません0パイルは3つあるので、を引く必要があります3

繰り返しの場合を考えてみましょう。3桁ごとに3つの完全な配置があります。つまり、A 3 3 = 6 A ^ 3_3 = 6A33=6ケースなので、6で割ります。

したがって、最終結果はans =(3 sum − 3)/ 6 ans =(3 ^(sum)-3)/ 6になります。a n s=3s u m3 / 6、ここで、sumは石の総数のバイナリ表現の数です1

ACコード

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<list>
#include<set>
#include<deque>
#include<vector>
#include<ctime>
using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ull)(1e9+7)
typedef pair<int, int> P;

int main() {
    
    
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    int T;scanf("%d", &T);
    while (T--) {
    
    
        ll n; scanf("%lld", &n);
        if (n & 1) printf("0\n");
        else {
    
    
            ll num = 0;
            while (n) {
    
    
                if (n & 1) num += 1;
                n >>= 1;
            }
            ll ans = (pow(3, num) - 3) / 6;
            printf("%lld\n", ans);
        }
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_45934120/article/details/108629525