A题
- 函数S(n)S(n)S(n)表示nnn的各位数字之和,给出nnn,问[1,n][1,n][1,n]之间有多少数字满足S(n+1)<S(n)S(n+1)\lt S(n)S(n+1)<S(n)
- 显然只有末尾数字是9的数才有这样的性质,这样的数个数是n+110\frac{n+1}{10}10n+1个
int main(){
int t, n;
cin >> t;
while(t--){
cin >> n;
cout << (n + 1) / 10 << "\n";
}
return 0;
}
B题
- 先往右后往左,也可以不走,题意需要仔细理解,停下的时候字符也只算一遍,不是重复计算,用两个dfsdfsdfs搜索就行了,比赛时候忘了初始化怎么也过不去,吐了
- 另外也积累了一个教训,函数传参别传stringstringstring,尤其是递归函数,会大大降低速度,因为会进行一次复制,可以通过传引用解决这个问题,或者稍微麻烦一点就写全局变量
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int Data[MAXN];
string x, y;
bool ok;
bool f;
void dfs(int i, int now){
if(now >= y.length()){
ok = true;
return;
}
if(i >= x.length()) return;
if(x[i] != y[now]) return;
if(f) dfs(i + 1, now + 1);
f = false;
dfs(i - 1, now + 1);
}
int main(){
int t;
ios::sync_with_stdio(false);
cin >> t;
while(t--){
cin >> x >> y;
int len = x.length();
ok = false;
for(int i=0;i<len;i++){
f = true;
if(x[i] == y[0]){
dfs(i, 0);
}
}
cout << (ok ? "YES" : "NO") << "\n";
}
return 0;
}
C题
- 模拟了一个足球比赛点球的情景,让你选择改变???,使得所需的点球次数最少,问最少需要几次
- 我以为是谁1多让谁赢,实际上是错的,我又以为是1和???加起来谁多让谁赢,实际也不对,比如1?1?1?0?0?1?1?1?0?0?1?1?1?0?0?这个例子,因为就两种情况,要么1赢,要么2赢,分别求取然后取最小值就行了
- 如果让1赢,要检查一下当1进球时候是否结束比赛,当2没进球时候是否结束比赛;如果让2赢,要检查一下当2进球时候是否结束比赛,当1没进球时是否结束比赛,这两种情况的剩余比赛场次是不同的
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int Data[MAXN];
int main(){
int t;
ios::sync_with_stdio(false);
string x;
cin >> t;
while(t--){
cin >> x;
int a, b, ans1, ans2;
a = b = ans1 = ans2 = 0;
for(int i=0;i<10;i+=2){
if(x[i] == '1' || x[i] == '?'){
a++;
ans1++;
if((10 - i) / 2 + b < a) break;
}else ans1++;
if(x[i + 1] == '1'){
b++;
ans1++;
}else{
ans1++;
if((8 - i) / 2 + b < a) break;
}
}
a = b = 0;
for(int i=0;i<10;i+=2){
if(x[i] == '1'){
a++;
ans2++;
}else{
ans2++;
if((8 - i) / 2 + a < b) break;
}
if(x[i + 1] == '1' || x[i + 1] == '?'){
ans2++;
b++;
if((8 - i) / 2 + a < b) break;
}else{
ans2++;
}
}
cout << min(ans1, ans2) << "\n";
}
return 0;
}
D题
- 题目的意思是输入两串字符串,将第一串的任意位置字符换成backspacebackspacebackspace删除前一个字符,问能不能达到第二个串
- 赛后我找到touristtouristtourist大神的本题程序,想看看为什么他能在这么快的时间内切掉这题,结果发现他的代码非常的清爽,思路也是格外的清奇,实在是吾辈楷模
- 从两串字符串后面向前看,因为如果第二串的最后一个字符在第一串后面没出现,那么这个字符肯定要被删除,且会连带它前面的字符一起被删掉,这样不停地寻找匹配的字符直到全部匹配即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 100;
const double eps = 1e-6;
int Data[MAXN];
int main(){
int t;
ios::sync_with_stdio(false);
string x, y;
cin >> t;
while(t--){
cin >> x >> y;
int n = x.length();
int m = y.length();
int i = n - 1;
bool ok = true;
for(int j=m-1;j>=0;j--){
while(i >= 0 && x[i] != y[j]){
i -= 2;
}
if(i < 0){
ok = false;
break;
}
i--;
}
cout << (ok ? "YES" : "NO") << '\n';
}
return 0;
}