• D. AB Graph from Codeforces Round #699 (Div. 2)


    题意:有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;
    
    }
    
  • 相关阅读:
    [转]三维成像原理
    loader如果你提前设width或height,loadComplete后显示不出来
    Flash调用Alchemy编译的代码时出现Error #1506的解决
    通过 IP 区分不同国家的用户
    Linux的进程组和会话
    Linux下安装 JDK(转备忘)
    程序中,调用Bison和Flex结合的小例子(语法分析中处理数据)
    从自己的程序中使用lex的一个小例子
    yum 删除软件要注意一点
    Linux下top命令
  • 原文地址:https://www.cnblogs.com/ruanbaiQAQ/p/14429360.html
Copyright © 2020-2023  润新知