CSP-S2021 回文

【题目链接】

	https://www.luogu.com.cn/problem/P7915

【思路分析】

  首先看到的时候,我想着每次如果取了元素i,那么如果在取到另一个之前两者间隔的最大值能够达到2n-cnt+1,则认为这次抽选是有效的。但是面对样例2的时候,发现它还得有最多的约束。但这种方案最后因为担心遇到冲突的点,而且在确定回文串的后半部分是从左/右取的相当麻烦,故没有写下去。(其实在题解区有一位大神给出了证明,每次取完之后都应该存在一个排列)。
  然后看了题解恍然大悟,只要第一次抽选把栈底确定下来,之后只要满足栈顶=栈底,即可进行取出。在代码实现时需要注意处理从自己一个栈里面取的时候元素个数应该>1,而从两个栈中取则没有这种约束。

【代码】

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int T;
int n;
const int maxn = 5e5+5;
int arr[maxn<<1];
int pos[maxn][2];
int ans[maxn<<1];

void print_ans(int flag)
{
	if(flag ==0)
	{
		for(int i=1;i<=2*n;i++)
		{
			if(ans[i]==0) cout<<"L";
			else if(ans[i]==1) cout<<"R";
			else cout<<"?";
		}
	}
	else
	{
		cout<<"-1";
	}
	cout<<endl;
}

void debug_print(int lptr,int rptr)
{
	/*
	cout<<"DBG:";
	cout<<"arr["<<lptr<<"]="<<arr[lptr]<<" ";
	cout<<"arr["<<rptr<<"]="<<arr[rptr];
	cout<<endl;
	*/
}


int main()
{
	cin>>T;
	while(T--)
	{
		cin>>n;
		memset(arr,0,sizeof(arr));
		memset(pos,0,sizeof(pos));
		for(int i=1;i<=2*n;i++)
		{
			cin>>arr[i];
			if(pos[arr[i]][0]==0)
				pos[arr[i]][0]=i;
			else
				pos[arr[i]][1]=i;
			if(pos[arr[i]][0]>pos[arr[i]][1]) swap(pos[arr[i]][0],pos[arr[i]][1]);
		}
		int lst_top = 0;
		int lst_bottom = 0;
		int rst_top = 0;
		int rst_bottom = 0;
		int flag = 1;//failed
		if(flag==1)
		{
			memset(ans,-1,sizeof(ans));
			//L first
			lst_top = 2;
			lst_bottom = pos[arr[1]][1]-1;
			rst_bottom = pos[arr[1]][1]+1;
			rst_top = 2*n;
			int cnt = 1;
			ans[cnt] = 0;//left
			ans[2*n-cnt+1]=0;
			flag = 0;
			while((lst_top<=lst_bottom || rst_top>=rst_bottom) && cnt<=n)
			{
				debug_print(lst_top,lst_bottom);
				debug_print(rst_top,rst_bottom);
				if(flag==1) break;
				flag = 1;
				if(arr[lst_top]==arr[lst_bottom] && lst_top<lst_bottom)
				{
					ans[++cnt]=0;
					ans[2*n-cnt+1]=0;
					lst_top++;
					lst_bottom--;
					flag = 0;
				}
				else if(arr[lst_top]==arr[rst_bottom])
				{
					ans[++cnt]=0;
					ans[2*n-cnt+1]=1;
					lst_top++;
					rst_bottom++;
					flag = 0;
				}
				else if(arr[rst_top]==arr[lst_bottom])
				{
					ans[++cnt]=1;
					ans[2*n-cnt+1]=0;
					rst_top--;
					lst_bottom--;
					flag = 0;
				}
				else if(arr[rst_top]==arr[rst_bottom] && rst_top>rst_bottom)
				{
					ans[++cnt]=1;
					ans[2*n-cnt+1]=1;
					rst_top--;
					rst_bottom++;
					flag = 0;
				}
			}
		}
		if(flag==1)
		{
			memset(ans,-1,sizeof(ans));
			//R first
			lst_top = 1;
			lst_bottom = pos[arr[2*n]][0]-1;
			rst_bottom = pos[arr[2*n]][0]+1;
			rst_top = 2*n-1;
			int cnt = 1;
			ans[cnt] = 1;//right
			ans[2*n-cnt+1]=0;
			flag = 0;
			while((lst_top<=lst_bottom || rst_top>=rst_bottom) && cnt<=n )
			{
				debug_print(lst_top,lst_bottom);
				debug_print(rst_top,rst_bottom);
				if(flag==1) break;
				flag = 1;
				if(arr[lst_top]==arr[lst_bottom] && lst_top<lst_bottom)
				{
					ans[++cnt]=0;
					ans[2*n-cnt+1]=0;
					lst_top++;
					lst_bottom--;
					flag = 0;
				}
				else if(arr[lst_top]==arr[rst_bottom])
				{
					ans[++cnt]=0;
					ans[2*n-cnt+1]=1;
					lst_top++;
					rst_bottom++;
					flag = 0;
				}
				else if(arr[rst_top]==arr[lst_bottom])
				{
					ans[++cnt]=1;
					ans[2*n-cnt+1]=0;
					rst_top--;
					lst_bottom--;
					flag = 0;
				}
				else if(arr[rst_top]==arr[rst_bottom] && rst_top>rst_bottom)
				{
					ans[++cnt]=1;
					ans[2*n-cnt+1]=1;
					rst_top--;
					rst_bottom++;
					flag = 0;
				}
			}
		}
		print_ans(flag);
	}
	return 0;
}
上一篇:CSP-S 2021 补题记录


下一篇:[CSP-S 2021] 回文【模拟】