CF1599A. Weights

題意

給出n個物品,第i個重量a[i](互不相同)
每次任意選一個物品放到秤的左右兩邊,使得放完之後 左>右 或 左<右
給出a[i] 和 大小關係s[i],構造方案

題解

必定有解

把a排序,假設當前選了LRLRLR,發現在最後加L可以瞬間反轉,在最前加R可以保持不變

即,當前選了一段連續的a[i],放的順序爲...LRLRLR...,
可以在頭部放一個相反的來 保持大小不變+保證交替序列,在尾部放一個相反的來 改變大小關係+保證交替序列

發現有多少段就要在尾部加上多少次(包括第一個),這樣放完之後剛好到n,所以可以倒推出第一個選的a[]

然後按順序擴展,維護a的選擇區間(以及交替情況,當前的每個a[i]在哪一邊p[i],實際由於是交替所以(i+p[i])%2相同),構造即可

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define ll long long
//#define file
using namespace std;

int n,i,j,k,l;
int a[200001];
char S[200001];
ll sumL,sumR;
pair<int,int> ans[200001];
//deque<pair<int,int> > d;
int L,R;

//bool operator < (type a,type b)
//{
//	return a.s<b.s || a.s==b.s && a.x<b.x;
//}
int get(char c)
{
	if (c=='L') return 0;
	return 1;
}

int main()
{
	#ifdef file
	freopen("CF1599A.in","r",stdin);
	#endif
	
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	scanf("%s",S+1);
	
	l=0;
	fo(i,1,n) l+=(i==1) || S[i]!=S[i-1];
	
	l=n-l+1; //l+get(S[1])-L=get
	L=R=l;
	ans[1]=pair<int,int>(a[l],get(S[1]));
	fo(i,2,n)
	if (S[i]==S[i-1])
	{
		--L;
		ans[i]=pair<int,int>(a[L],((l+get(S[1])-L)%2+2)%2);
	}
	else
	{
		++R;
		ans[i]=pair<int,int>(a[R],((l+get(S[1])-R)%2+2)%2);
	}
	
	fo(i,1,n)
	printf("%d %c\n",ans[i].first,(ans[i].second==0)?'L':'R');
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章