給定一個 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; }
題目大意:給定包含元素個數爲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; }
題目大意:給定一個數 \(n\),當前操做者,能夠在一下兩個操做中任選一個:string
若 \(n\) 能整除奇數,而且能保證整除奇數後的結果大於1,能夠考慮讓 \(n\) 整除奇數,整除後的結果更新n,參與接下的操做。it
若 \(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的,繼續舉例以下
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贏 上面是因式分解,沒有奇數因子的狀況
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贏
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贏
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 } } }
把上面的思路轉換一下就是下方的 ↓
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; }