zoukankan      html  css  js  c++  java
  • [lougu1341]无序字母对

    Description:

    给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

    Solution:

    欧拉回路裸题,注意大写字母和小写字母在ASCII码中不连续,还有要求最小字典序(用multiset存图每次有限遍历最小的)

    code:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<set>
    using namespace std;
    const int MAXX=10000;
    multiset<int>to[MAXX];
    int f[MAXX],deg[MAXX],q[MAXX];
    int n,tot,ans,cnt,s=-1;
    bool vis[MAXX],num[MAXX],flag;
    inline int find(int x){
    	if(f[x]==x)return x;
    	else return f[x]=find(f[x]);
    }
    inline void dfs(int x){
    	for(set<int>:: iterator it=to[x].begin();it!=to[x].end();it=to[x].begin()){
    		int y=*it;
            to[x].erase(it);
            to[y].erase(to[y].find(x));
            dfs(y);
    	}
    	q[++tot]=x;
    }
    int main(){
       cin>>n;
       for(int i=0;i<=99;++i)f[i]=i;
       for(int i=1;i<=n;++i){
       	char a,b;
       	int x,y;
       	cin>>a>>b;
       	x=a-'A';y=b-'A';
       	int u=find(x);
       	int v=find(y);
       	f[u]=v;
       	vis[x]=1;vis[y]=1;
       	deg[x]++;deg[y]++;
       	to[x].insert(y);
       	to[y].insert(x);
       }
       for(int i=0;i<=99;++i){
       	  if(!vis[i])continue;
          num[find(i)]=1;
       }
       for(int i=0;i<=99;++i){
       	if(!vis[i])continue;
       	ans+=num[i];
       	if(s==-1)s=i;
        if(deg[i]&1){
        	cnt++;
        	if(flag)continue;
        	s=i;
        	flag=1;
        }
       }
       if((cnt!=0&&cnt!=2)||ans>1){
       	cout<<"No Solution"<<endl;
       	return 0;
       }
       dfs(s);
       for(int i=tot;i>=1;--i){
       	char ss='A'+q[i];
       	cout<<ss;
       }
       return 0;
    }
    
  • 相关阅读:
    快速排序
    jenkins 升级
    JAVA中的Random()函数
    拦截器
    两个链表合并不加入新的链表空间
    统计字符 比如aaabbcca----3a2b1c1a
    折半查找两种实现
    字符串偏移
    java值传递
    基于zookeeper实现配置集中管理【转】
  • 原文地址:https://www.cnblogs.com/ARTlover/p/9546623.html
Copyright © 2011-2022 走看看