zoukankan      html  css  js  c++  java
  • 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;
    
    }
    
  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/ruanbaiQAQ/p/14429360.html
Copyright © 2011-2022 走看看