Codeforces Round 906 (Div. 2)扫题

C题:Qingshan Loves Strings 2

本题提供一个01的字符串,然后可以将01插入到字符串的任何位置,不限次数。问怎么插入可以满足完全不对称的条件。如果不可能满足输出-1。

那么对于这题来说很明显的一件事情是只要左右对应的字符相等的话就需要去添加01来保持不等。所以说添加的过程就是这样做的。如果左右两边都是1的话,那么就给左边位置添加01,如果左右两边都是0的话,那么就给右位置添加01。

但是有个不那么容易看出来的问题是如何去判断能否凑成题目中要求的字符串。由于想要是完全不对称字符串,而添加的字符串是01,是一个偶数。所以无论怎么添加奇偶性都不会发生变化。但奇数长度的字符串一定不行。所以第一步判断字符串长度可以检验符不符合。

又有添加的字符串时01,不改变01的相对数量。所以判断0和1的数量是否相等是另一个检验条件。

那么只要满足这两个条件,然后按照步骤逐渐的去加一定可以变成符合要求的字符串。

#include <bits/stdc++.h>
#include <windows.h>
using namespace std;

string addition = "01";

void init()
{
}

void solve()
{
	int n;cin>>n;
	string s;
	cin>>s;
	vector<int> vt;
	int zero_num = count(s.begin(),s.end(), '0');
	int one_num = n-zero_num;
	if (n%2!=0||zero_num!=one_num)
	{
		cout<<-1<<"\n";
		return ;
	}
	//效验通过,开始根据两端的情况来进行插入
	int l = 0, r = n-1;
	while (l<r)
	{
//		cout<<"l="<<l<<" r="<<r<<endl;
//		cout<<"s="<<s<<endl;
		if (s[l]!=s[r])
		{
			l++;r--;
//			cout<<"l="<<l<<" r="<<r<<endl;
			continue;
		}
		if (s[l]=='0')
		{
			vt.push_back(r+1);
//			cout<<"进来了\n"; 
			s.insert(r+1, addition);
			r+=2;
		}
		else
		{
			vt.push_back(l);
			s.insert(l, addition);
			r+=2;
		}
	}
	cout<<vt.size()<<"\n";
	for (int i=0;i<vt.size();i++)
	{
		cout<<vt[i]<<" ";
	}
	cout<<"\n";
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int t;
	cin>>t;
	while (t--)
	{
		init();
		solve();
	}
	
	return 0;
}

D题:D. Doremy's Connecting Plan

本题要求建立一个连通图,而且在建立过程中要求两个部分的数值和大于等于i*j*c。

那么对于这道题来说两个连通块想要连接就必须有至少一个连通块的数值a[i]>=i。

当然这是最小的条件。

那么对于有1节点参与的来说:a[i]+a[1]>=i。正好要求a[i]达到最小的要求。所以采取都与1连接是最优的选择,可以将要求降到最低。毕竟只要有一个a[i]>=i后后面再有节点相连就可以继承a[i]的值了。而无论怎么连最起码也得至少有一个a[i]>=i 。所以都与1连是最优的选择。

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5+10; 
int n, c;
int a[maxn];
void solve()
{
	cin>>n>>c;
	for (int i=1;i<=n;i++)	cin>>a[i];
	vector<pair<int, int> > b(n+1);
	for (int i=2;i<=n;i++)
	{
//		cout<<i<<endl;
		b[i-2] = {a[i]-i*c, i};
	}
	sort(b.begin(), b.end(), greater<pair<int, int> >());
	bool f = 1;
	int s = a[1];
	for (int i=0;i<b.size();i++)
	{
		pair<int, int> p = b[i];
		int x = p.first;
		int number = p.second;
		if (x+s>=0) s+=a[number];
		else{
			f = 0;
			break;
		}
	}
	if (f) cout<<"YES\n";
	else cout<<"NO\n";
}

signed main()
{
	int t;
	cin>>t;
	while (t--)
	{
		solve();
	}
	
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值