Codeforces Round 943 (Div. 3) A-D题解

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题

题意:

思路:

一开始想用同余,但是感觉才到c题,应该没必要。

根据2023ICPC杭州赛中的一道题(Operator Precedence 有兴趣的伙伴可以搜一下)特值法的启发,想到这题也可以用特值法

这题让你给出满足条件的一组数,然后给出的这组数是通过取模运算建立联系的。那么如果我把起点设置好了,后面的数也就都出来了。

易错点是除数必须大于余数!起点设置成比500大的数(_{}x_{i}<=500)即可(此后a_{i}必然大于x_{i}

a2%a1=x1 \rightarrowa1+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;
	}

}

Thank you! 然后虽然有些迟但是还是要祝大家五一快乐

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值