一些 Codeforce Content 補題記錄

Codeforces Round #651 (Div. 2)

1370A. Maximum GCD

給定一個 n,求(1~n)中任意組合對的最大的公約數。數組

思路:若是 \(n\) 是偶數,那麼最大公約數爲 $ n / 2$ ,反之 爲 \((n - 1) / 2\)。但因爲C++ int類型在進行除法時會向下取整因此:cout << n / 2 << endl;spa

void solve() {
    int n;
    cin >> n;
    cout << n / 2 << endl;
}

1370B. GCD Compression

題目大意:給定包含元素個數爲2n的數組a,刪去其中2個元素,剩下的元素兩兩組合求和,構成包含n-1個元素的數組b,要求數組b中的元素共有的因子大於1,輸出數組a兩兩選擇數據所處的位置.code

基本思路:數組a中元素數值的構成要麼奇數,要麼偶數,考慮到奇數+奇數=偶數,偶數+偶數=偶數,能夠構造出和值爲偶數的n-1個數,這樣,共有因子是2.ci

AC代碼get

void solve() {
    int n;
    cin >> n;
    n = 2 * n;
    vector<int> a(n), b[2];
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        b[a[i] % 2].push_back(i);
    }
    vector<pair<int, int> > ans;
    for (int j = 0; j < 2; j++) {
        while (b[j].size() > 1)
            ans.push_back({b[j][b[j].size() - 1], b[j][b[j].size() - 2]}),
                b[j].pop_back(), b[j].pop_back();
    }
    while (ans.size() > n / 2 - 1)
        ans.pop_back();
    for (auto it : ans)
        cout << it.first + 1 << " " << it.second + 1 << endl;
}

1370C. Number Game

題目大意:給定一個數 \(n\),當前操做者,能夠在一下兩個操做中任選一個:string

  1. \(n\) 能整除奇數,而且能保證整除奇數後的結果大於1,能夠考慮讓 \(n\) 整除奇數,整除後的結果更新n,參與接下的操做。it

  2. \(n-1\) 的結果大於1,能夠考慮讓 \(n-1\) 的結果更新 \(n\),參與接下的操做。io

若當前操做者,什麼操做也作不了,那麼當前操做者認輸。ast

輸出該次比賽的獲勝者。class

樣例模

Ashishgup(簡寫爲A),FastestFinger(簡寫爲F)
 
1
FastestFinger
 
n=1,輪到A什麼都作不了,F贏
 
 
2
Ashishgup
 
n=2,輪到A,n=2-1=1
n=1,輪到F什麼都作不了,A贏
 
3
Ashishgup
 
n=3,輪到A,n=3/3=1
n=1,輪到F什麼都作不了,A贏
 
4
FastestFinger
 
n=4,輪到A,n=4-1=3
n=3,輪到F,n=3/3=1
n=1,輪到A什麼都作不了,F贏
 
5
Ashishgup
 
n=5,輪到A,n=5/5=1
n=1,輪到F什麼都作不了,A贏
 
6
FastestFinger
 
n=2*3,輪到A,n=2*3/3=2
n=2,輪到F,n=2-1=1
n=1,輪到A什麼都作不了,F贏
 
 
12
Ashishgup
 
n=2*2*3,輪到A,n=2*2*3/3=2*2
n=2*2,輪到F,n=2*2/2=2
n=2,輪到A,n=2-2=1
n=1,輪到F什麼都作不了,A贏

只靠樣例這點數據,該題是難以AC的,繼續舉例以下

  1. 下面是因式分解,只有偶數因子的狀況
Ashishgup(簡寫爲A),FastestFinger(簡寫爲F)
 
8
FastestFinger
 
n=8=2*2*2,輪到A,n=8-1=7
n=7,輪到F,n=8/7=1
n=1,輪到A什麼都作不了,F贏
 
上面是因式分解,沒有奇數因子的狀況
  1. 有偶數因子(偶數因子的個數大於等於2),同時也有奇數因子
Ashishgup(簡寫爲A),FastestFinger(簡寫爲F)
 
12
Ashishgup
 
n=12=2*2*3,輪到A,n=2*2*3/3=2*2
n=2*2,輪到F,n=4-1=3
n=3,輪到A,n=3/3=1
n=1,輪到F什麼都作不了,A贏
 
 
120
Ashishgup
 
n=120=2*2*2*3*5,輪到A,n=2*2*2*3*5/(3*5)=2*2*2,注意,將奇數因子一次耗盡
n=2*2*2,輪到F,n=8-1=7
n=7,輪到A,n=7/7=1
n=1,輪到F什麼都作不了,A贏
  1. 有偶數因子(偶數因子的個數等於1),同時也有奇數因子
Ashishgup(簡寫爲A),FastestFinger(簡寫爲F)
 
只有一個奇數因子
6
FastestFinger
 
n=6=2*3,輪到A,n=2*3/3=2
n=2,輪到F,n=2-1=1
n=1,輪到A什麼都作不了,F贏
 
奇數因子個數大於等於2
30
Ashishgup
 
n=30=2*3*5,輪到A,n=2*3*5/5=2*3
n=2*3,輪到F,n=2*3/3=2
n=2,輪到A,n=2-1=1
n=1,輪到F什麼都作不了,A贏
 
 
奇數因子個數大於等於2
90
Ashishgup
 
n=90=2*3*3*5,輪到A,n=2*3*3*5/(3*5)=2*3
n=2*3,輪到F,n=2*3/3=2
n=2,輪到A,n=2-1=1
n=1,輪到F什麼都作不了,A贏

AC Code 1

string name[2] = {"Ashishgup\n", "FastestFinger\n"};
void solve() {
    ll n;
    cin >> n;
    // 特判 n == 1 和 n == 2
    if (n == 1)
        cout << name[1];
    else if (n == 2 || n % 2)
        cout << name[0];
    else {
        int cnt0 = 0, cnt1 = 0;  // 統計偶數因子和奇數因子的個數
        // 質因數分解
        for (int i = 2; i * i <= n; ++i) {
            if (n % i == 0)
                while (n % i == 0) {
                    n /= i;
                    if (i == 2)
                        cnt0++;
                    else
                        cnt1++;
                }
        }
        if (n > 1)
            cnt1++;
        if (cnt1 == 0)
            cout << name[1];  //只有偶數因子
        else if (cnt0 >= 2)
            cout << name
                    [0];  //有偶數因子(偶數因子的個數大於等於2),同時也有奇數因子
        else if (cnt0 ==
                 1) {  //有偶數因子(偶數因子的個數等於1),同時也有奇數因子
            if (cnt1 == 1)
                cout << name[1];  //奇數因子個數是1
            else
                cout << name[0];  //奇數因子個數大於等於2
        }
    }
}

AC Code 2

把上面的思路轉換一下就是下方的 ↓

FastestFinger贏的條件 $n = \(1,\)n = 2^x$,其中(x> 1)和 \(n =2⋅p\) ,其中 \(p\) 是大於3的素數,不然Ashishgup獲勝。

// 素數斷定
bool check_prime(int n) {
    for (int i = 2; i < min(N, n); i++)
        if (n % i == 0)
            return 0;
    return 1;
}

void solve() {
    ll n;
    cin >> n;
    bool lose = (n == 1);
    if (n > 2 && n % 2 == 0) {
        if ((n & (n - 1)) == 0)
            lose = 1;
        else if (n % 4 != 0 && check_prime(n / 2))
            lose = 1;
    }
    cout << (!lose ? "Ashishgup" : "FastestFinger") << endl;
}

1370D. Odd-Even Subsequence

相關文章
相關標籤/搜索