zoukankan      html  css  js  c++  java
  • hdu 1116 Play on Words

    我的思路:

    用俩个数组分别记录出现过的节点的入度和出度,这样只有一个字母的入度比出度大1,一个字母的出度比入度大1,或者是所有有字母的出度和入度都一样,他就是欧拉路

    但这样还差了一个联通性的判断 于是我用了一个辅助数组 f[] 用并查集的方式判断是否连通

    代码:

    #include<iostream>
    #include<string>
    using namespace std;
    int f[30],c[30],r[30];
    char s[1005];
    int find(int x)  
    {  
        if(x==f[x])  
            return f[x];  
        f[x]=find(f[x]);  
        return f[x];  
    }  
    void Union(int x,int y)  
    {  
        int a=find(x);  
        int b=find(y);  
        if(a==b)  
            return ;  
        f[a]=b;  
        return ;  
    }  
    
    void init()
    {
    	for(int i=0;i<26;i++)
    		f[i]=i;
    	memset(c,0,sizeof(c));
    	memset(r,0,sizeof(r));
    }
    int main()
    {
    	int i,j,cas,n;
    	cin>>cas;
    	while(cas--)
    	{
    		init();
    		cin>>n;
    		for(i=0;i<n;i++)
    		{
    			cin>>s;
    			int a=s[0]-'a';
    			int b=s[strlen(s)-1]-'a';
    			Union(a,b);
    			r[b]++;
    			c[a]++;//累加 节点的入度和出度
    		}
    		int count=0;
    		for(i=0;i<26;i++)//计算根节点数目
    		{
    			if(i==find(i)&&(r[i]||c[i]))
    				count++;
    		}
    		if(count!=1)//判断是否连通
    		{
    			cout<<"The door cannot be opened."<<endl;
    			continue;
    		}
    		int p1=0,p2=0;
    		for(i=0;i<26;i++)
    		{
    			if(c[i]>r[i])
    				p1+=c[i]-r[i];
    			if(r[i]>c[i])
    				p2+=r[i]-c[i];
    		}
    		if((p1==0&&p2==0)||(p1==1&&p2==1))
    		  cout<<"Ordering is possible."<<endl;
    		else 
    			cout<<"The door cannot be opened."<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    冒泡排序
    跑马(行转列,列转行)
    选择排序
    day06-迭代器
    day05-装饰器作业
    day07-生成器
    day08-内置函数和匿名函数
    day09-正侧表达式
    144-SpringBoot的编码问题?
    143-SprinBoot如何使用Servlet?
  • 原文地址:https://www.cnblogs.com/nanke/p/2125782.html
Copyright © 2011-2022 走看看