CF1481D AB Graph

D. AB Graph

我是SB

比赛的时候由于有一种情况没有输出 Yes,挂了,赛后加上就过了。

而且话说这天早上刚考完 WC2021。不觉得WC的这道题和他很像吗。我当时吓出一身冷汗。

好啦不说废话,来分析本题。我们不要把它想得过于复杂,我们分成几种情况。我们令 \(w(u,v)\) 为从 \(u\) 出发,到 \(v\) 的这条边上的字符,令 \(x,y\) 表示这两种字符。

如果存在某两点 \(u,v\),使得 \(w(u,v)\)\(w(v,u)\) 相同,那么我们可以对于任意 \(m\),构造出形如 \(u,v,u,v,u,\cdots\) 的答案,最后的串为 \(x,x,x\cdots\)。显然回文。

如果不存在,说明一定是两点之间的边,有为 a 的,也有为 b 的。如果 \(m\) 为奇数,那么随便找两点我们可以构造如下答案 \(u,v,u,v,\cdots,u,v\),那么经过的边形成的串为 \(x,y,x,\cdots,y,x\),明显回文。

我们只需要处理剩下的 \(m\) 为偶数的情况。我们需要找到如下图的结构:

我们可以在 \(O(n^2)\) 的时间内找到这样的 \(1,2,3\)。易证,在目前讨论的大前提下,对于任意 \(n\geq 3\),都能至少找出一组这样的结构。我们可以构造出以下两种答案,根据 \(m\)\(4\) 的余数决定选择哪一种。

  • 第一种,经过的点为 \(3,1,2,1,3,1,2,3,\cdots,3,1,2,1,3,1,2\),得到的串为 \(x,x,y,y,x,x,\cdots,x,x\)。显然回文。
  • 第二种,经过的点为 \(1,3,1,2,1,3,1,2,\cdots,1,3,1,2,1\),得到的串为 \(y,x,x,y,y,x,x,y,\cdots,y,x,x,y\)。显然回文。

其他情况输出 NO

//Don't act like a loser.
//This code is written by huayucaiji
//You can only use the code for studying or finding mistakes
//Or,you'll be punished by Sakyamuni!!!
//#pragma GCC optimize("Ofast","-funroll-loops","-fdelete-null-pointer-checks")
//#pragma GCC target("ssse3","sse3","sse2","sse","avx2","avx")
#include<bits/stdc++.h>
using namespace std;

int read() {
	char ch=getchar();
	int f=1,x=0;
	while(ch<'0'||ch>'9') {
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') {
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}

const int MAXN=1e3+10; 

int n,m;
char ch[MAXN][MAXN];

signed main() {
	int t=read();
	while(t--) {
		n=read();
		m=read();
		
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=n;j++) {
				cin>>ch[i][j];
			}
		}
		
		bool flag=0;
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=n;j++) {
				if(i!=j&&ch[i][j]==ch[j][i]) {
					printf("YES\n");
					for(int k=1;k<=m;k+=2) {
						printf("%d %d ",i,j);
					}
					if((m+1)&1) {
						printf("%d\n",i);
					}
					else {
						printf("\n");
					}
					flag=1;
					break;
				}
			}
			if(flag) {
				break;
			}
		}
		if(flag) {
			continue;
		}
		if(m&1) {
			printf("YES\n");
			for(int i=1;i<=m;i+=2) {
				printf("1 2 ");
			}
			cout<<endl;
			continue;
		}
		int a,b,c;
		bool fa=0,fb=0,f=0;
		for(int i=1;i<=n;i++) {
			fa=fb=0;
			for(int j=1;j<=n;j++) {
				if(ch[i][j]=='a') {
					fa=1;
					a=j;
				}
				if(ch[j][i]=='a') {
					fb=1;
					b=j;
				}
			}
			if(fa&&fb) {
				c=i;
				f=1;
				break;
			}
		}
		if(!f) {
			printf("NO\n");
			continue;
		}
		printf("YES\n");
		if(m%4==0) {
			for(int i=0;i+4<=m;i+=4) {
				printf("%d %d %d %d ",c,b,c,a);
			}
			printf("%d\n",c);
		}
		else {
			for(int i=0;i+4<=m;i+=4) {
				printf("%d %d %d %d ",b,c,a,c);
			}
			printf("%d %d %d\n",b,c,a);
		}
	}
	return 0;
}

posted @ 2021-02-06 15:18  huayucaiji  阅读(207)  评论(0编辑  收藏  举报