Codeforces Round #585 (Div. 2) ABCD

传送门

A:签到

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int main()
    {
    	int a1,a2,k1,k2,n;
    	cin>>a1>>a2>>k1>>k2>>n;
    	//minn
    	if(a1*(k1-1)+a2*(k2-1)>=n)
    	{
    		cout<<0<<" ";
    	}
    	else
    	{
    		int maxn=n-a1*(k1-1)-a2*(k2-1);
    		maxn=min(a1+a2,maxn);
    		cout<<maxn<<" ";
    	}
    	//maxn
    	if(k2>k1)
    	{
    		int sum=min(n/k1,a1);
    		n-=sum*k1;
    		int sum1=min(n/k2,a2);
    		cout<<sum+sum1<<endl;
    	}
    	else
    	{
    		int sum=min(n/k2,a2);
    		n-=sum*k2;
    		int sum1=min(n/k1,a1);
    		cout<<sum+sum1<<endl;
    	}
    	return 0;
    } 

B:前缀和

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int a[200010];
    int per[200010];
    int main()
    {
    	int n;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		int x;
    		cin>>x;
    		if(x<0)
    		{
    			a[i]=-1;
    		}
    		else
    		{
    			a[i]=1;
    		}
    	}
    	per[0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		per[i]=per[i-1]*a[i];//前缀积是正还是负数
    	}
    	ll ans1=0,ans2=0,sum1=0,sum2=0;
    	for(int i=1;i<=n;i++)
    	{
    		if(per[i]==1)
    		{
    			ans1++;//前面正数得个数
    		}
    		else{
    			ans2++;//前面负数得个数
    		} 
    		if(per[i]==1)//如果当前位置为正数 直接运算
    		{
    			sum1+=ans1;
    			sum2+=ans2;
    		}
    		else//如果为负数 
    		{
    			sum1+=ans2-1;// 正数的数量即为前面负数的数量
    			sum2+=ans1+1;// 负数的数量即为前面正数的数量加当前这个负数
    		}
    		//cout<<sum2<<" "<<sum1<<endl;
    	}
    	cout<<sum2<<" "<<sum1<<endl;
    	return 0;
    }

C:

1.当ab或者ba是奇数的时候输出-1,不然一定有解。

2.当ab和ba都为奇数的时候,ab可以自己交换,然后再跟ba交换,花费两次。对于每个ab直接进行交换即可。同理ba也是

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int>v[3];
int main()
{
	int n;
	cin>>n;
	string s1,s2;
	cin>>s1>>s2;
	int ans1=0,ans2=0;
	for(int i=0;i<s1.size();i++)
	{
		if(s1[i]=='a')
		{
			ans1++;
		}
		if(s2[i]=='a')
		{
			ans1++;
		}
		
		if(s1[i]=='b')
		{
			ans2++;
		}
		if(s2[i]=='b')
		{
			ans2++;
		}
	}
	if(s1==s2)
	{
		cout<<0<<endl;
		return 0;
	}
	if(ans1%2||ans2%2)
	{
		cout<<-1<<endl;
		return 0;
	}
	else
	{
		s1=" "+s1;
		s2=" "+s2; 
		for(int i=1;i<=s1.size();i++)
		{
			if(s1[i]==s2[i]){
				continue;
			}
			if(s1[i]=='a'){
				v[1].push_back(i);
				continue;
			}
			else
			{
				v[2].push_back(i);
			}
		}
		int ans=0;
		int flag=0;
		if(v[1].size()%2)
		{
			flag=v[1].back();
			v[2].push_back(v[1].back());
			v[1].pop_back();
			ans++; 
		}
		
		ans=ans+v[1].size()/2+v[2].size()/2;
		cout<<ans<<endl;
		
		if(flag)
		cout<<flag<<" "<<flag<<endl;
		
		if(v[1].size()>0)
		for(int i=0;i<v[1].size()-1;i+=2)
		{
			cout<<v[1][i]<<" "<<v[1][i+1]<<endl;
			
		}
		
		if(v[2].size()>0)
		for(int i=0;i<v[2].size()-1;i+=2)
		{
			cout<<v[2][i]<<" "<<v[2][i+1]<<endl;
		}
		
	}
	return 0;
}

D:博弈,如果不存在 ?则直接比较大小可即。如果存在 很容易想到两边可以抵消。然后抵消最后只剩下一边存在?然后B只能控制9 因为不管M拿什么 B都可以互补使得总值为9 多以判断?多的那边 ?数量/2*9+当前值是否等于另一边的值

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
	int n;
	cin>>n;
	string s;
	cin>>s;
	s=" "+s;
	int ans1=0,sum1=0;
	int ans2=0,sum2=0;
	for(int i=1;i<=n/2;i++)
	{
		if(s[i]=='?')
		ans1++;
		else
		{
			sum1+=s[i]-'0';
		}
	}
	for(int i=n/2+1;i<=n;i++)
	{
		if(s[i]=='?')
		ans2++;
		else
		{
			sum2+=s[i]-'0';
		}
	}
	if(ans1==ans2)
	{
		if(sum1==sum2)
		{
			cout<<"Bicarp"<<endl;
		}
		else
		{
			cout<<"Monocarp"<<endl;
		}
		return 0;
	}
	if(ans1>ans2)
	{
		int sum=(ans1-ans2)/2;
		if(sum*9+sum1==sum2)
		cout<<"Bicarp"<<endl;
		else
		{
			cout<<"Monocarp"<<endl;
		}
		return 0;
	}
	if(ans1<ans2)
	{
		int sum=(ans2-ans1)/2;
		if(sum*9+sum2==sum1)
		cout<<"Bicarp"<<endl;
		else
		{
			cout<<"Monocarp"<<endl;
		}
		return 0;
	}
	return 0;
}

E:据说是状压DP。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值