「题解」Codeforces 1394C Boboniu and String

「题解」Codeforces 1394C Boboniu and String

orz qyc

两个串相似实际上是两个字符串 'N' 和 'B' 的数量一致。

sixi 个 'N',yi 个 'B',tx 个 'N',y 个 'B'。

分类讨论一下 dist(s,t)x,xi 以及 y,yi 大小关系不同的四种情况下的取值。

发现四种情况分别为:

xyxi+yi,(xy)+xiyi,max(xix,yiy),max(xxi,yyi)

对出现的六个式子求 max 恰好为答案,具体为何同样可以分类讨论四种情况。

二分答案转判定,就变成要求 max 里面六个值都 mid

发现实际上是对 x,y,xy 的取值范围作出限制。

后面就很简单了,算出各自的取值范围,然后看前两项不等式的差出来的范围是否和后一项的范围有交即可,构造方案枚举个 x 随便怎么构造都可。

其实分类讨论有很多细节,但是这里仅给出主要思路不商讨细节部分。

//Code by do_while_true
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
typedef long long ll;
template <typename T> T Max(T x, T y) { return x > y ? x : y; }
template <typename T> T Min(T x, T y) { return x < y ? x : y; }
template <typename T> T Abs(T x) { return x < 0 ? -x : x; }
template <typename T> T chkmax(T &x, T y) { return x = x > y ? x : y; }
template <typename T>
T &read(T &r) {
	r = 0; bool w = 0; char ch = getchar();
	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
	while(ch >= '0' && ch <= '9') r = (r << 3) + (r <<1) + (ch ^ 48), ch = getchar();
	return r = w ? -r : r;
}
const int N = 300010;
const int INF = 100000000;
int n, a[N], b[N];
//a:N  b:B
char ch[N];
bool check(int x) {
	int l1, r1, l2, r2, l3, r3;
	l1 = -INF, r1 = INF; l2 = 0, r2 = INF; l3 = 0; r3 = INF;
	for(int i = 1; i <= n; ++i) {
		l1 = Max(l1, a[i]-b[i]-x);
		r1 = Min(r1, a[i]-b[i]+x);
		l2 = Max(l2, a[i]-x);
		r2 = Min(r2, a[i]+x);
		l3 = Max(l3, b[i]-x);
		r3 = Min(r3, b[i]+x);
	}
	if(l2 < 0 || l3 < 0) return 0;
	if(l1 > r1 || l2 > r2 || l3 > r3) return 0;
	int l4 = l2 - r3, r4 = r2 - l3;
	return r1 >= l4 && l1 <= r4;
}
signed main() { //freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
	read(n);
	if(n == 1) {
		scanf("%s", ch+1);
		puts("0");
		printf("%s\n", ch+1);
		return 0;
	}
	for(int i = 1; i <= n; ++i) {
		scanf("%s", ch+1);
		int len = std::strlen(ch+1);
		for(int j = 1; j <= len; ++j)
			if(ch[j] == 'N') ++a[i];
			else ++b[i];
	}
	int l = 0, r = INF, mid, ans = 0;
	while(l <= r) {
		mid = (l + r) >> 1;
		if(check(mid)) ans = mid, r = mid-1;
		else l = mid+1;
	}
	printf("%d\n", ans);
	int l1, r1, l2, r2, l3, r3;
	l1 = -INF, r1 = INF; l2 = 0, r2 = INF; l3 = 0; r3 = INF;
	for(int i = 1; i <= n; ++i) {
		l1 = Max(l1, a[i]-b[i]-ans);
		r1 = Min(r1, a[i]-b[i]+ans);
		l2 = Max(l2, a[i]-ans);
		r2 = Min(r2, a[i]+ans);
		l3 = Max(l3, b[i]-ans);
		r3 = Min(r3, b[i]+ans);
	}
	int l4 = l2 - r3, r4 = r2 - l3;
	l = Max(l1, l4); r = Min(r1, r4);
	for(int i = l2; i <= r2; ++i) {
		int _l = i - r3, _r = i - l3;
		if(Max(_l, l) <= Min(r, _r)) {
			int p = Max(_l, l);
			if(i || (i-p)) {
				for(int j = 1; j <= i-p; ++j) printf("B");
				for(int j = 1; j <= i; ++j) printf("N");
				return 0;
			}
			else {
				p = Min(r, _r);
				if(i || (i-p)) {
					for(int j = 1; j <= i-p; ++j) printf("B");
					for(int j = 1; j <= i; ++j) printf("N");
					return 0;
				}
			}
		}
	}
	return 0;
}
posted @   do_while_true  阅读(48)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

This blog has running: 1845 days 1 hours 33 minutes 45 seconds

点击右上角即可分享
微信分享提示