样例1过不去求调
查看原帖
样例1过不去求调
765061
AsiraeM楼主2023/4/20 23:04

qwq

#include<bits/stdc++.h>
namespace xcy{
int vector,main,queue,set,pair,string,cin,cout;//在自己的名字空间里面可以为所欲为(
const int MAXV=500005/*最大局面数*/,go[4][2]{{0,1},{0,-1},{1,0},{-1,0}};
int hash[11][11][11][11][11][11],
	cq[MAXV<<1][7],ch,ct,	q[MAXV<<1],qh,qt,	tmp,tmp2,a,b,c,d,e,f,g,nx,ny,
	mins[MAXV]/*最小步数*/,win[MAXV]/*-1=输,0=不鸡道,1=赢*/, 
	t,id,n,m,i,j,k,map[11][11],
	head[MAXV],cnt,rd[MAXV]/*入度*/,
	bx,by,rx1,ry1,rx2,ry2,nxt;
std::bitset<MAXV>vis/*判断是否访问过*/;
struct Edge{int to,pre;}ed[MAXV<<3];
inline void add(int F,int T){ed[++cnt].to=T;ed[cnt].pre=head[F];head[F]=cnt;}
inline void fread(int &X){X=0;char C=getchar();while(!isdigit(C))C=getchar();while(isdigit(C))X=(X<<3)+(X<<1)+(C^48),C=getchar();}
inline void fout(int X){if(!X){putchar('0'),putchar(' ');return;}char c[25]{};int Len=0;while(X)c[++Len]=X%10+'0',X/=10;for(;Len;--Len)putchar(c[Len]);putchar(' ');}
void init()
{
	int num=0;
	for(bx=1;bx<=10;++bx)
		for(by=1;by<=10;++by)
			for(rx1=1;rx1<=10;++rx1)
				for(ry1=1;ry1<=10;++ry1)
					for(rx2=1;rx2<=10;++rx2)
						for(ry2=1;ry2<=10;++ry2)
							if(rx1==rx2?ry1<ry2:rx1<rx2)//既处理重复状态,又处理红方棋子重合
								hash[bx][by][rx1][ry1][rx2][ry2]=hash[bx][by][rx2][ry2][rx1][ry1]=++num;
}
#define push(Bx,By,Rx1,Ry1,Rx2,Ry2,Nxt)cq[++ct][0]=Bx,cq[ct][1]=By,cq[ct][2]=Rx1,cq[ct][3]=Ry1,cq[ct][4]=Rx2,cq[ct][5]=Ry2,cq[ct][6]=Nxt;
void mian()
{
	init();
	fread(id),fread(t);
	while(t--){
	vis.reset();
	ch=qh=1;
	cnt=ct=qt=bx=by=rx1=ry1=rx2=ry2=nxt=0;
	memset(win,0,sizeof(win));
	memset(rd,0,sizeof(rd));
	memset(mins,0x3f,sizeof(mins));
	memset(head,0,sizeof(head));
	memset(ed,0,sizeof(ed));
	fread(n),fread(m);
	for(i=1;i<=n;++i,getchar())
		for(j=1;j<=m;++j)
		{
			map[i][j]=getchar();
			if(map[i][j]=='X')bx=i,by=j;
			else if(map[i][j]=='O'&&!rx1)rx1=i,ry1=j;
			else if(map[i][j]=='O')rx2=i,ry2=j;
		}
	//for(i=1;i<=n;++i)
	//	for(j=1;j<=m;++j)
	//		putchar(map[i][j]),putchar(j==m?'\n':' ');
	//bfs连边,到所有必败态为止 
	push(bx,by,rx1,ry1,rx2,ry2,1);
	vis[hash[bx][by][rx1][ry1][rx2][ry2]]=1;
	while(ch<=ct)
	{
		a=cq[ch][0],b=cq[ch][1],c=cq[ch][2],d=cq[ch][3],e=cq[ch][4],f=cq[ch][5],g=cq[ch++][6],tmp=hash[a][b][c][d][e][f];
		//fout(a),fout(b),fout(c),fout(d),fout(e),fout(f),fout(g),putchar('\n');
		if(a==1||a==c&&b==d||a==e&&b==f){win[tmp]=-1;mins[tmp]=0;q[++qt]=tmp;continue;}
		if(g)
		{
			for(i=0;i<4;++i)
			{
				nx=c+go[i][0],ny=d+go[i][1];
				if(!(nx&&ny&&nx<=n&&ny<=m&&map[nx][ny]!='#'&&(nx!=e||ny!=f)))continue;
				tmp2=hash[a][b][nx][ny][e][f],++rd[tmp],add(tmp2,tmp);
				if(!vis[tmp2])vis[tmp2]=1,push(a,b,nx,ny,e,f,0);
			}
			for(i=0;i<4;++i)
			{
				nx=e+go[i][0],ny=f+go[i][1];
				if(!(nx&&ny&&nx<=n&&ny<=m&&map[nx][ny]!='#'&&(nx!=c||ny!=d)))continue;
				tmp2=hash[a][b][c][d][nx][ny],++rd[tmp],add(tmp2,tmp);
				if(!vis[tmp2])vis[tmp2]=1,push(a,b,c,d,nx,ny,0);
			}
			if(!rd[tmp])win[tmp]=-1,mins[tmp]=0,q[++qt]=tmp; 
		}
		else
		{
			for(i=0;i<3;++i)
			{
				nx=a+go[i][0],ny=b+go[i][1];
				if(!(nx&&ny&&nx<=n&&ny<=m&&map[nx][ny]!='#'))continue;
				tmp2=hash[nx][ny][c][d][e][f],++rd[tmp],add(tmp2,tmp);
				if(!vis[tmp2])vis[tmp2]=1,push(nx,ny,c,d,e,f,1);
			}
			if(!rd[tmp])win[tmp]=-1,mins[tmp]=0,q[++qt]=tmp; 
		}
	}
	//bfs判输赢
	vis.reset();
	while(qh<=qt)
	{
		tmp=q[qh++];
		if(win[tmp]==-1)
		{
			for(i=head[tmp];i;i=ed[i].pre)
			{
				j=ed[i].to;
				if(win[j]==0)win[j]=1,mins[j]=mins[tmp]+1;
				if(!vis[j])q[++qt]=j,vis[j]=1;
			}
		}
		else
		{
			for(i=head[tmp];i;i=ed[i].pre)
			{
				j=ed[i].to;
				--rd[j];
				if(win[j]==0)mins[j]=mins[tmp]+1;
				if(!rd[j])
				{
					if(win[j]==0)win[j]=-1;
					if(!vis[j])q[++qt]=j,vis[j]=1;
				}
			}
		}
	}
	tmp=hash[bx][by][rx1][ry1][rx2][ry2];
	//fout(bx),fout(by),fout(rx1),fout(ry1),fout(rx2),fout(ry2);
	if(win[tmp]==1)std::cout<<"Red "<<mins[tmp]<<std::endl;
	else if(win[tmp]==0)std::cout<<"Tie"<<std::endl;
	else if(win[tmp]==-1)std::cout<<"Black "<<mins[tmp]<<std::endl;
}}
}
int main()
{
	xcy::mian();
	return 0;
}
2023/4/20 23:04
加载中...