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 second
typedef 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 second
typedef 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 second
typedef 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;
}