给定一个 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; }