A Digits Sum
题目大意
S(x)为x各个位上的数的和,问在1~n这n个数中有多少个数满足S(x + 1) < S(x)
主要思路
只有发生进位才会满足S(x + 1) < S(x),统计9,19,29..等个数即可
AC代码
#include <bits/stdc++.h>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;int a[N];signed main(void){int T;cin >> T;while(T--){cin >> n;int res = 0;res = n / 10;if(n % 10 == 9) res++;cout << res << endl;}return 0;}
B Reverse String
题目大意
给一个字符串s,一个字符串t,问能否通过在任意位置先向右遍历s一个长度(可以为0),再向左遍历一个长度(可以为0)来得到字符串t
主要思路
找到s[i] == t[0]的位置枚举向右遍历的长度,由于t字符串长度固定,那么向左的长度也能确定,将字符串拼接判断是否等于t即可,模拟
AC代码
#include <bits/stdc++.h>using namespace std;#define debug(a) cout << #a << " = " << a << endl;#define x first#define y secondtypedef pair<int, int> P;const int N = 200010;int n;int main(void){int T;cin >> T;while(T--){string s1, s2;cin >> s1 >> s2;int x = s1.find(s2);if(x != -1) puts("YES");else{bool flag = false;for(int i = 0; i < s1.size(); i++){if(s1[i] == s2[0]){string s = "";for(int len = 0; len < s2.size(); len++)//枚举长度{s.clear();int pos;for(int j = i; j <= i + len && j < s1.size(); j++)//先向右{s += s1[j];pos = j;}pos--;while(pos >= 0 && s.size() != s2.size())//再向左{s += s1[pos];pos--;}if(s == s2){flag = true;break;}}}}if(flag) puts("YES");else puts("NO");}}return 0;}
C Penalty
题目大意
两队一人一球踢点球,1表示进球,0表示没进球,?表示未知,问能否通过修改?为1或0来让点球用最少的局数结束,当1队的进球数+剩余局数 < 另一队进球数时结束
主要思路
一共只有10局比赛,我们统计?个数,枚举每一种情况判断即可
或者考虑由于求局数最小,则让?全为1或者全为0取局数最小值即可
AC代码
#include <bits/stdc++.h>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;int ans;int f(string s, int st, int n){int cnt = 0;for(int i = 0; i < s.size(); i++){if(s[i] == '?'){if((st >> cnt) & 1){s[i] = '1';}else s[i] = '0';cnt++;}}int t1 = 0, cnt1 = 5;int t2 = 0, cnt2 = 5;for(int i = 0; i < 10; i++){if(s[i] == '1' && i % 2 == 0) t1++;else if(s[i] == '1' && i % 2 == 1) t2++;if(i % 2 == 0) cnt1--;else cnt2--;if(t1 + cnt1 < t2){return i + 1;}else if(t2 + cnt2 < t1){return i + 1;}}return (int)10;}signed main(void){int T;cin >> T;while(T--){int ans = 11;string s;cin >> s;int cnt = 0;for(int i = 0; i < s.size(); i++){if(s[i] == '?') cnt++;}for(int i = 0; i < 1 << cnt; i++){ans = min(ans, f(s, i, cnt));}cout << ans << endl;}return 0;}
D Backspace
题目大意
给一个字符串s和一个字符串t,每次可以写入一个字符或者删除上一个输入的字符(如果上一个没输入字符则不用删除,相当于不输入当前字符),问能否通过s得到字符串t
主要思路
考虑从前往后遍历,如果s[i] == t[j]那么i++, 否则i += 2,这样我们最后还得考虑剩余的字符串是否是偶数个,如果是奇数则不成立。
于是我们考虑从后往前遍历,如果s[i] == t[j]那么i—, 否则i -= 2,这样在匹配成功时不需考虑最后剩余字符数为奇数还是偶数,全部删除即可
AC代码
#include <bits/stdc++.h>using namespace std;int main(){int T;cin >> T;while(T--){string s, t;cin >> s >> t;for(int i = s.size() - 1; i >= 0; i--){if(s[i] == t.back()) t.pop_back();else i--;if(t.size() == 0) break;}if(t.size() == 0) puts("YES");else puts("NO");}return 0;}
