A 取因数
题目大意
在纸上写一个数字 n,双方每次选择 n 的一个因数,然后划掉 n 并在纸上写下 n 减去这个数字的差使之成为新的 n,最后写数字 0 的人输。Alice先手。
主要思路
- 奇数的因数都是奇数,因此奇数一定会变成偶数
- 偶数可以通过-1变成奇数
- 那么如果先手是偶数,那么可以通过-1维持对手是奇数,自己一直是偶数,持续到自己为2时,对手为1,对手必输,先手必胜
结论:偶数先手必胜,奇数先手必输
AC代码
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 200010;int n, a[N];signed main(void){cin >> n;if(n % 2) puts("Bob");else puts("Alice");return 0;}
B A + B
题目大意
中文题
主要思路
n最大是100,因为k只有2,所以分3种情况即可
- k == 0,可以从1020往后枚举n个
- k == 1,可以枚举a = 10, b = 1, c = 11, 每轮b++, c++
- k == 2,枚举a = 1, b = 11, c = 12,每轮a++, b为两个a合并(比如a = 1,b变为11,a为2,b变为22),c = a + b,也就是a + aa == aa + a形式
AC代码
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 200010;int n, a[N];int f(int x){int t = x;int cnt = 0;while(x){x /= 10;cnt++;}return t * (int)pow(10, cnt) + t;}signed main(void){int n, k;cin >> k >> n;if(k == 0){int t = 1020;for(int i = 0; i < n; i++){cout << t << endl;t++;}}else if(k == 1){int a = 10, b = 1, c = 11;for(int i = 0; i < n; i++){cout << a << b << c << endl;b++, c++;}}else{int a = 1, b = 11, c = 12;for(int i = 0; i < n; i++){cout << a << b << c << endl;a++, b = f(a), c = a + b;}}return 0;}
C 取钱
题目大意
中文题
主要思路
我们先预处理出用a[i]纸币能凑不超过a[i + 1]金额的金额最大值sum和纸币张数cnt。
读入每一个金额b,先二分出小于等于b的a[i]的最大值,然后获得纸币数量最大值为cnt[i - 1] + (b - sum[i - 1]) / a[i], 金额为sum[i - 1] + (b - sum[i - 1]) / a[i] + a[i]
核心思想:贪心,从小到大将每一个a[i]的数量最大化
AC代码
#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <string>#include <cmath>#include <unordered_map>#include <queue>#include <map>using namespace std;#define int long long#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 200010;int n, a[N];int cnt[N];int sum[N];signed main(void){cin >> n;for(int i = 1; i <= n; i++) cin >> a[i];a[n + 1] = 1e18+1;for(int i = 1; i <= n; i++){int t = (a[i + 1] - sum[i - 1] - 1) / a[i];//t为最大金额小于a[i + 1],会用到最多多少a[i]cnt[i] = cnt[i - 1] + t;//总纸币数量sum[i] = sum[i - 1] + a[i] * t;//总价}int T;cin >> T;while(T--){int num;cin >> num;int l = 0, r = n + 1;while(l < r)//二分小于等于当前num的最大面额{int mid = l + r + 1 >> 1;if(a[mid] <= num) l = mid;else r = mid - 1;}cout << sum[l - 1] + (num - sum[l - 1]) / a[l] * a[l] << ' ' << cnt[l - 1] + (num - sum[l - 1]) / a[l] << endl;}return 0;}
