题意:有n个点,两两之间都有权为'a'或'b'的边,没有重边。你需要去找一条路径,使得路径组成的字符串是长度为(m)的回文串。
做法:由于只有a和b两种边权,所以:
①假设能找到一条边为(a,b,'a'or'b')和(b,a,'a'or'b'),则可以在这两点间反复横跳;
②如果没有这样一条边:
则需要找到下述3个点:(a,b,'a')(b,a,'b')(b,c,'a')(c,b,'b')
如果(m\%4==2):假设m==6,则从a点出发:a->b->a->b->c->b->c,构造的串是'abaaba'
如果(m\%4==0):假设m==8,则从b点出发:b->a->b->a->b->c->b->c->b,构造的串是'babaabab'
代码写得比较糟,不建议参考
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define fastio ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
double pi = acos(-1);
const double eps = 1e-9;
const int inf = 1e9 + 7;
const int maxn = 1e5 + 10;
ll mod = 1e9 + 7;
char c[1010][1010];
int in[2][1010], out[2][1010];
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)in[0][i] = in[1][i] = out[0][i] = out[1][i] = 0;
for (int i = 1; i <= n; i++)
{
getchar();
for (int j = 1; j <= n; j++)
{
scanf("%c", &c[i][j]);
if (c[i][j] == '*')continue;
int flag = (c[i][j] == 'a');//边的类型
out[flag][i]++;//flag型出边++
in[flag][j]++;//flag型入边++
}
}
int a = 0, b = 0, ok = 0;
for (int i = 1; !a && i <= n; i++)
for (int j = i + 1; j <= n; j++)
if (c[i][j] == c[j][i])//可以直接来回走的类型
{
a = i, b = j;
break;
}
if (a)
{
printf("YES
");
printf("%d ",b);
while (m--)
{
printf("%d ", a);
if (m > 0)
printf("%d ", b), m--;
}
printf("
");
continue;
}
if (m & 1)//m为奇数随便选2个点来回走
{
printf("YES
");
printf("%d ", 1);
while (m--)
{
printf("%d ", 2);
if (m > 0)
printf("%d ", 1), m--;
}
printf("
");
}
else
{
//剩下的肯定出边是a则入边是b,否则ba,看能否找得到3个满足条件的点
for (int i = 1; i <= n; i++)
{
if (in[0][i] >= 1 && out[1][i] >= 1 && in[1][i] >= 1 && out[0][i] >= 1)
{
ok = i;
break;
}
}
if (!ok)
{
printf("NO
");
continue;
}
for (int i = 1; !a && i <= n; i++)
{
if (i == ok)continue;
for (int j = i + 1; j <= n; j++)
{
if (j == ok)continue;
if (c[i][ok] == c[ok][j])
{
a = i, b = j;
break;
}
}
}
if (!a)
printf("NO
");
else
{
printf("YES
");
if (m % 4 == 0)
{
printf("%d ", ok);
for (int i = 1; i <= m / 4; i++)
printf("%d %d ", a, ok);
for (int i = 1; i <= m / 4; i++)
printf("%d %d ", b, ok);
}
else
{
printf("%d ", a);
for (int i = 1; i <= m / 4; i++)
printf("%d %d ", ok, a);
printf("%d %d ", ok, b);
for (int i = 1; i <= m / 4; i++)
printf("%d %d ", ok, b);
}
printf("
");
}
}
}
return 0;
}