A
逆序输出两个字符串
#include <bits/stdc++.h>
using namespace std;
int main() {
string a,b;
cin >> a >> b;
cout << b << a;
return 0;
}
B
先用掉 a ,再用掉 b,输出剩余部分
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main() {
LL a, b,c;
cin >> a >> b >> c;
if(a < c) c -= a,a = 0;
else a -= c,c = 0;
if(b < c) c -= b,b = 0;
else b -= c,c = 0;
cout << a <<' ' << b;
return 0;
}
C
找到大于 或 等于 \(x\) 的最小质数
线性筛 + 二分
直接暴力也能过。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 100;
bool st[N];
int k,pri[N];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
for(int i = 2;i <= N; ++i) {// 线性筛
if(!st[i]) pri[k ++] = i;
for(int j = 0;pri[j] <= N / i; ++j) {
st[pri[j] * i] = 1;
if(i % pri[j] == 0) break;
}
}
int x;
cin >> x;
int l = 0,r = k;
while(l < r) {// 二分
int mid = l + r>> 1;
if(pri[mid] >= x) r = mid;
else l = mid + 1;
}
cout << pri[l];
return 0;
}
D
题目大意
你和机器人玩剪刀石头布,机器人输入一个长度为\(N\) 的序列,\(r\)代表石头,\(s\) 代表剪刀,\(p\)代表布
每\(K\) 次为一个回合,第一个回合你可以出任何手势,从第二个回合开始你出的手势不能和上一个回合相同
即\(hand[i] != hand[i - k]\) ,每次获胜,分别赢 \(r,s,p\) 个分数,平局不计分,问你最大的获胜分数
思路
观察题目发现,从第二轮开始,你每次出的手势,都要考虑上一轮出过的,不能重复。
那么,我们首先考虑,赢下当前这局所需要的手势,是不是上轮出过的,如果出过,就和机器人相同的手势保证平局,否则就出必胜手势。
我们用\(vis\) 数组来保存,当前第\(i\) 位是否出过必胜手势
用 \(t\) 数组来保存机器人出的手势序列
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
char t[N];
bool vis[N];
int r,s,p,n,k,ans = 0;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin >> n >> k >> r >> s >> p ;
for(int i = 1;i <= n; ++i) {
cin >> t[i];
if(i - k > 0 && vis[i - k] && t[i] == t[i - k]) continue;
// 如果当前不是第一轮,并且vis[i-k]出过必胜手势,并且t[i]==t[i-k],说明我们只能平局
if(t[i] == 'r') ans += p;
if(t[i] == 's') ans += r;
if(t[i] == 'p') ans += s;
vis[i] = 1;// 当前局势出过必胜手势
}
cout << ans;
return 0;
}