Educational Codeforces Round 137 (Rated for Div. 2) D

D. Problem with Random Tests

题意:给定一个长度为 n n n 的01串,从中选出两个子串 a a a, b b b,记 f(s) 为以s为二进制表示下的十进制数。求 f(a) 0R f(b) 的最大值(输出为不带前导0的01串)。
思路:不难想到两个子串中的一个串必定要选择原串(保留最多的1),然后考虑另一个串怎么取,我们当然希望另一个串最好要尽量使得原串高位的0可以通过异或变为1。本题关键信息:生成数据随机,每个位置是0或1的概率分别是1/2,故一块长度是20的全为1的连续块的概率是1e-6,长度更长概率更低,故可以认为全1连续块不会很长(一开始看到“数据随机生成”,不知道有什么用,现在学会啦!!!套路)。记串的第一块全1连续块的第一个1的位置是i,第一块全1连续块的最后一个位置是j(那么第j+1的位置是0),遍历k=i+1~j+1,将第一个全1连续块的第一个1(第i位置)挪到第k位置(保证第j+1位的0(第一块全1连续块后的第一个0)通过或运算后是1(贪心 尽量让高位为1))。
代码

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

#define int long long
int n;
string s;

signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>s;
	int i;
	for(i=0;i<n;++i) if(s[i]=='1') break;
	if(i==n) { //全0 
		cout<<0<<'\n';
	}else{
		int j=i;
		while(j<n-1 && s[j+1]=='1') j++;
		string ans=s;
		for(int k=i+1;k<=j+1;++k){
			string str="";
			for(int kk=0;kk<k;++kk) str+='0';
			for(int kk=i;kk<n-(k-i);++kk) str+=s[kk];
			string str1="";
			for(int kk=0;kk<n;++kk){
				if(s[kk]=='1' || str[kk]=='1') str1+='1';
				else str1+='0';
			}
			if(str1>ans) ans=str1;
		}
		bool ok=false;
		for(int i=0;i<n;++i){
			if(ans[i]=='1'){
				cout<<1;
				ok=true;
			}else if(ok) cout<<0;
		}
		if(!ok) cout<<0;
		cout<<'\n';
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值