A 题
题意:
思路:
爆搜,不断更新maxx
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,k;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
int maxx=0;
int ans=0;
for(int j=1;j<x;j++){
if(maxx==max(maxx,__gcd(x,j)+j))continue;
else{
maxx=max(maxx,__gcd(x,j)+j);
ans=j;
}
}
cout<<ans<<endl;
}
return 0;
}
B题
题意:
思路:
二分+find查找(不用二分单纯循环遍历会爆TLE)
查找时在b串中查a前缀形成的字符串是否为b子序列(注意不一定是子串,只要b中有和a前缀对应的01序列(不一定连续)即可)(审题口牙!)
外层套二分用来迅速找到符合的前缀
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int a1,b1;
cin>>a1>>b1;
string a;
string b;
cin>>a>>b;
int cnt=0;
int l=0;
int r=a1-1;
while(l<r){
int mid=(l+r+1)>>1;
string p=a.substr(0,mid+1);
int dex=0;
int fl=0;
for(int w=0;w<p.length();w++){
if(b.find(p[w],dex)==EOF){
fl=1;
break;
}
else{
dex=b.find(p[w],dex)+1;
}
}
if(fl==0)
{
l=mid;
//cout<<p<<endl;
}
else r=mid-1;
}
cnt=l+1;
if(l==0){
if(b.find(a[0])==EOF){
cout<<0<<endl;
continue;
}
}
cout<<cnt<<endl;
}
return 0;
}
C题
题意:
![](https://img-blog.csdnimg.cn/direct/8f0158f6b35e4ae0991322ced2109e02.png)
思路:
一开始想用同余,但是感觉才到c题,应该没必要。
根据2023ICPC杭州赛中的一道题(Operator Precedence 有兴趣的伙伴可以搜一下)特值法的启发,想到这题也可以用特值法
这题让你给出满足条件的一组数,然后给出的这组数是通过取模运算建立联系的。那么如果我把起点设置好了,后面的数也就都出来了。
易错点是除数必须大于余数!起点设置成比500大的数(<=500)即可(此后
必然大于
)
a2%a1=x1 a1+x1=x2 递推求结果
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int n;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=0;i<n;i++){
int m;
cin>>m;
int a[m-1]={0};
int b[m]={0};
for(int j=0;j<m-1;j++){
cin>>a[j];
}
b[0]=a[0]+501;
for(int j=1;j<m;j++){
b[j]=b[j-1]+a[j-1];
}
for(int j=0;j<m;j++){
cout<<b[j]<<" ";
}
cout<<endl;
}
return 0;
}
D题
题意:
思路:
存储走到每个点时的积分(一直走到该点然后停下直到比赛结束的分数)即:前缀和+后面停留该点得到的分数,然后找最大作比较。
注意:1.不会出现中间停几回合再走的情况 2.每一回合都会得到这个点的分数(得到分再决定走不走,审题注意)
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
for(int i=1;i<=t;i++){
int n,k,a,b;
cin>>n>>k>>a>>b;
map<int,int>ak;
map<int,int>bk;
map<int,int>aans;
map<int,int>bans;
for(int j=1;j<=n;j++){
cin>>ak[j];
}
for(int j=1;j<=n;j++){
cin>>bk[j];
}
int max1=bk[a]*k;
int max2=bk[b]*k;
aans[1]=bk[a];
bans[1]=bk[b];
for(int j=2;j<=min(k,n);j++){
aans[j]+=bk[ak[a]]+aans[j-1];
max1=max(aans[j]+bk[ak[a]]*(k-j),max1);
a=ak[a];
}
for(int j=2;j<=min(k,n);j++){
bans[j]+=bk[ak[b]]+bans[j-1];
max2=max(bans[j]+bk[ak[b]]*(k-j),max2);
b=ak[b];
}
if(max1>max2) cout<<"Bodya"<<endl;
else if(max1<max2) cout<<"Sasha"<<endl;
else cout<<"Draw"<<endl;
}
}