1. 程式人生 > 其它 >CF1394C Boboniu and String

CF1394C Boboniu and String

題解

好妙的一道題。

將每個串都抽象成二維平面上的一個點 \((x_i,y_i)\)\(x_i\) 為其中 N 的個數,\(y_i\)B 的個數。

二分答案 \(mid\),那麼對於一個點 \((x_i,y_i)\),能通過不超過 \(mid\) 次操作到達它的點的範圍是一個凸六邊形,所以可以用不等式描述這個範圍:

\[\begin{aligned} &x_i-mid\le x\le x_i+mid\\ &y_i-mid\le x\le y_i+mid\\ &x_i-y_i-mid\le x-y\le x_i-y_i+mid\\ \end{aligned} \]

對所有的 \(i\)

,將以上範圍求交即可。

有些細節。

程式碼

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <utility>
using namespace std;
#define For(Ti,Ta,Tb) for(int Ti=(Ta);Ti<=(Tb);++Ti)
#define Dec(Ti,Ta,Tb) for(int Ti=(Ta);Ti>=(Tb);--Ti)
template<typename T>
void Read(T &_x){
	_x=0;int _f=1;
	char _ch=getchar();
	while(!isdigit(_ch)) _f=(_ch=='-'?-1:_f),_ch=getchar();
	while(isdigit(_ch)) _x=_x*10+(_ch^48),_ch=getchar();
	_x*=_f;
}
template<typename T,typename... Args>
void Read(T &_x,Args& ...others){
	Read(_x);Read(others...);
}
typedef long long ll;
typedef pair<int,int> Point;
const int N=3e5+5,Len=5e5+5;
int n;
Point poi[N];
pair<bool,Point> Check(int mid){
	int xmin=-Len,xmax=Len,ymin=-Len,ymax=Len,xymin=-Len,xymax=Len;
	For(i,1,n){
		xmin=max(xmin,poi[i].first-mid);
		xmax=min(xmax,poi[i].first+mid);
		ymin=max(ymin,poi[i].second-mid);
		ymax=min(ymax,poi[i].second+mid);
		xymin=max(xymin,poi[i].first-poi[i].second-mid);
		xymax=min(xymax,poi[i].first-poi[i].second+mid);
	}
	xmin=max(0,xmin),ymin=max(0,ymin);
	if(xmin>xmax||ymin>ymax||xymin>xymax) return {0,{0,0}};
	int xymn=xmin-ymax,xymx=xmax-ymin;
	if(xymn>xymax||xymx<xymin) return {0,{0,0}};
	xymax=min(xymax,xymx);
	xymin=max(xymin,xymn);
	int pxmax=min(ymax+xymax,xmax),pymax=min(pxmax-xymin,ymax);
	return {1,{pxmax,pymax}};
}
int main(){
	Read(n);
	char temp[Len];
	For(i,1,n){
		scanf("%s",temp+1);
		int len=strlen(temp+1),cnt=0;
		For(j,1,len){
			cnt+=temp[j]=='N';
		}
		poi[i]={cnt,len-cnt};
	}
	int l=0,r=1e6;
	Point ans;
	while(l<r){
		int mid=(l+r)>>1;
		if(Check(mid).first) r=mid,ans=Check(mid).second;
		else l=mid+1;
	}
	printf("%d\n",l);
	For(i,1,ans.first) putchar('N');
	For(i,1,ans.second) putchar('B');
	return 0;
}
Written by Alan_Zhao