codeforces1392D Omkar and Bed Wars

https://codeforces.com/contest/1392/problem/D

sb题写了一年,写的巨复杂

把入度为1的不合法的点拿出来讨论就行了,如果两个相邻的都是不合法的,直接换一条边改两个,否则就该当前这个不合法的边

有更简单的写法,直接把连续的L或R拿出来,长度/3就行了

我的代码就别看了,写得巨丑

#include
#define pb push_back
using namespace std;
typedef long long ll;

const int maxl=4e5+10;

int n,m,cas,k,cnt,tot,ans;
int a[maxl],b[maxl],rudu[maxl];
char s[maxl],ch[maxl];
int in[maxl][2],out[maxl][2]; 

inline int id(int x)
{
	if(x<1) return n+x;
	if(x>n) return x-n;
	return x;
}

inline void prework()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		in[i][0]=in[i][1]=out[i][0]=out[i][1]=0;
		rudu[i]=0;
	}
	scanf("%s",ch+1);
	int st=1;ch[n+1]='0';
	while(ch[st]==ch[st+1])
		st++;
	if(st+1>n)
		st=0;
	cnt=0;
	for(int i=st+1;i<=n;i++)
		s[++cnt]=ch[i];
	for(int i=1;i<=st;i++)
		s[++cnt]=ch[i];
	for(int i=1;i<=n;i++)
	{
		if(s[i]=='L')
		{	
			in[id(i-1)][1]=i,out[i][0]=id(i-1);
			rudu[id(i-1)]++;
		}	
		else
		{
			in[id(i+1)][0]=i;out[i][1]=id(i+1);
			rudu[id(i+1)]++;
		}	
	}
} 

inline bool sb(int i)
{
	if(rudu[i]!=1)
		return false;
	if(in[i][0] && s[i]=='L')
		return false;
	if(in[i][1] && s[i]=='R')
		return false;
	return true;
}

inline void mainwork()
{
	ans=0;int l,r=0;char c,rc;
	for(int i=1;i<=n;i++)
	if(sb(i) )
	{
		ans++;
		if(sb(id(i+1)))
		{
			if(s[i]=='L')
			{
				in[i][1]=0;rudu[i]--;
				s[id(i+1)]='R';
				in[id(i+2)][0]=id(i+1);rudu[id(i+2)]++;
			}
			else
			{
				in[id(i+2)][0]=0;rudu[id(i+2)]--;
				s[id(i+1)]='L';
				in[i][1]=id(i+1);rudu[i]++;
			}
		}
		else
		{
			if(in[i][0] && s[i]!='L')
			{
				s[i]='L';
				rudu[id(i+1)]--;in[id(i+1)][0]=0;
				rudu[id(i-1)]++;in[id(i-1)][1]=i;
			}
			else if(in[i][1] && s[i]!='R')
			{
				s[i]='R';
				rudu[id(i-1)]--;in[id(i-1)][1]=0;
				rudu[id(i+1)]++;in[id(i+1)][0]=i;
			}
		}
	}
}

inline void print()
{
	printf("%d\n",ans);
}

int main()
{
	int t=1;
	scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

你可能感兴趣的:(codeforces1392D Omkar and Bed Wars)