日常刷题2025-3-13

日常刷题2025-3-13

经验+1

题目求最大值最小,或者最小值最大都可以考虑二分。一般都是二分配一个贪心。

配一道比较难判断出二分的题https://codeforces.com/contest/2070/problem/C

C. Kevin and Binary Strings

rating:1200

https://codeforces.com/problemset/problem/2048/C

思路:小巧思

为了使结果的位数足够多,我们选择的一个子串应该尽可能长,所以就是整个字符串。考虑如何选择第二个字符串能让结果最大?

结果要大,则字符串中的1一定要多,且1的位置最好是要高一点。我们找到第一个字符串第一个不为1的位置,把它变为1是最好的,假设在p位置。则我们需要一个长度为n-p的字符串。整个字符串中每个长度为n-p的字符串都有可能,所以我们要枚举所有情况。

枚举了所以情况如何判断哪种情况更优呢?发现此题的数据范围比较小,假设我们枚举了一个长度为n-p的字符串,我们暴力计算出它与第一个选出的字符串XOR后的字符串,我们发现,字符串的比较方式刚好适用于二进制数的比较方式。这样我们就可以根据选出来的字符串与第一个字符串XOR后得到的新字符串的相互比较来判断哪种选择方式更优。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

std::string ck(std::string a, std::string b){
	int n=a.size();
	std::string ret(n,'0');
	for(int i=0;i<n;i++){
		if(a[i]!=b[i]) ret[i]='1';
	}
	return ret;
}

void solve(){
	std::string s; std::cin>>s;
	int n=s.size();
	int p;
	for(p=0;p<n&&s[p]=='1';p++);
	if(p==n){
		std::cout<<1<<' '<<n<<' '<<1<<' '<<1<<'\n';
		return;
	}
	int len=n-p;
	std::string x=s.substr(p,len);
	std::string ans;
	int ansl=0,ansr=len-1;
	for(int i=0;i+len-1<n;i++){
		std::string t=s.substr(i,len);
		if(i==0){
			ans=ck(x, t);
		}else{
			std::string tmp=ck(x,t);
			if(tmp>ans){
				tmp=ans;
				ansl=i;
				ansr=i+len-1;
			}
		}
	}

	std::cout<<1<<' '<<n<< ' '<<ansl+1<<' '<<ansr+1<<'\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}
posted @ 2025-03-13 11:08  califeee  阅读(9)  评论(0)    收藏  举报