Codeforces Round 879 (Div. 2) (A-D)题解

A. Unit Array

题意

最小操作数使得序列和sum>=0,连乘积cnt=1,保证数组内只有+1和-1

题解

考虑到数组内只有+1和-1,那么可以统计+1,-1的个数,奇偶讨论即可

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
int a[N];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		int n;cin>>n;
		int x=0,y=0,sum=0,cnt=1;
		int ans=0;
		rep(i,1,n)
		{
			cin>>a[i];
			if(a[i]==1)	x++;
			else y++;
			sum+=a[i];
			cnt*=a[i];
		}
		if(y%2!=0)
		{
			ans++;
			sum+=2;
			cnt=1;
			y--;
		}
		if(sum<0)
		{
			while(sum<0&&y>=2)
			{
				sum+=4;
				y-=2;
				ans+=2;
			}
		}
		cout<<ans<<endl;
		
	}

}

B. Maximum Strength

题意

两个数字l,r,在l到r之间选两个数字,使得这两个数字对应位差的绝对值的和最大

题解

答案需要有尽量多的9草能保证最大,那么考虑除第一个对位不一样的外,其余全都是一个9一个0的形式

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
int a[N];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		string l,r;
		cin>>l>>r;
		int n=r.size();
		while((int)l.size()<n)
		{
			l='0'+l;
		}
		int ans=0;
		rep(i,0,n-1)
		{
			if(l[i]!=r[i])
			{
				ans=(n-1-i)*9+abs(r[i]-l[i]);
				break;
			}
		}
		cout<<ans<<endl;
	}

}

C. Game with Reversing

题意

A,B两人在S和T两个字符串上博弈,A的操作是选择一个字符使得其变成自己想要的任意一个字符,B的操作是选择一个字符串使其反转,A的目的是在尽量少的步数内使S=T,B的目的步数尽量多,问最少多少步可以使S=T

题解

实际上可以令B只操作T字符串,A只操作S字符串,A在操作次数为奇数时,T字符串不动,为偶数时,T字符串反转,那么只需要考虑S和T的字符差异数和S和reverse(T)的字符差异数即可

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
int a[N];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		string s,t;
		int n;
		cin>>n;
		cin>>s>>t;
		int l=0,r=0;
		int len=s.size();
		
		rep(i,0,len-1)	if(s[i]!=t[i])	l++;
		
		reverse(t.begin(),t.end());
		
		rep(i,0,len-1)	if(s[i]!=t[i])	r++;
		int ans=inf;
		if(l%2==1)
		{
			ans=min(ans,l*2-1);
		}
		else
		{
			ans=min(ans,l*2);	
		}
		if(r%2==1)
		{
			ans=min(ans,r*2);
		}
		else
		{
			if(r>0)	ans=min(ans,r*2-1);
			else ans=min(ans,2ll);
		}
		cout<<ans<<endl;
	}
	

}

D. Survey in Class

题意

已知学生数和提问数,以及每位学生所会题目的区间l[i],r[i],若题目在某学生的区间内,那么该学生得分+1,否则得分-1,问在提问结束后,学生分数最高和分数最低的差值最大是多少

(提问什么题目未知)

题解

得分最大值学生和得分最小值学生区间有四种情况

设a为得分最大值的学生,b为得分最小值的学生,则答案为 (\left |a \right |-\left | a\cap b\right |)*2 

可以通过枚举a,直接使用 min_r , max_l , min_len 来取得b

1.a,b左相交(b在a左)  此时cnt=r[a]-r[b]

2.a,b右相交(b在a右),此时cnt=l[b]-l[a]

3.b在a内,此时cnt=len[a]-len[b]

4.a,b不相交,视为1,2的拓展,此时cnt=len[a]

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"NO"<<endl
#define YES cout<<"YES"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9 + 7;
const int N = 2e6 + 10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
int l[N],r[N],len[N];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T = 1;
	cin >> T;
	while (T--)
	{
		int n,m;cin>>n>>m;
		int max_l=0,max_r=0,min_l=inf,min_r=inf,min_len=inf;
		rep(i,1,n)	cin>>l[i]>>r[i],len[i]=r[i]-l[i]+1;
		rep(i,1,n)
		{
			max_l=max(max_l,l[i]);
			max_r=max(max_r,r[i]);
			min_len=min(min_len,len[i]);
			min_l=min(min_l,l[i]);
			min_r=min(min_r,r[i]);
		}
		int ans=0;
		rep(i,1,n)
		{
			ans=max(ans,min(len[i],r[i]-min_r));
			ans=max(ans,min(len[i],max_l-l[i]));
			ans=max(ans,min(len[i],len[i]-min_len));
		}
		cout<<ans*2<<endl;
		
	}
	

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值