uvaLive 5139 (world final 1990 - Washington) Rare Order

来源:互联网 发布:笔记本电池激活软件 编辑:程序博客网 时间:2024/06/05 14:50

       题意是给定一个字符串的排列规则,即这个排序是按照特定的字符排序排下来的,要求输出已经给出来的全部字符的排列顺序。这个题是用拓扑排序做的,首先将每两个字符串能得到的规则进行比较,然后得到一张有向图。然后寻找出度为0的,则为最小,然后删掉所有以此的出度。以此类推。这里因为只有字母,所以主要复杂度就在于全部字符的排列规则的判定。我用向量处理这里未知的字符串数量,用时惊人啊,不过还是1Y了。下面是代码。

 

#include<iostream>#include<cstdio>#include<algorithm>#include<string>#include<cstring>#include<vector>using namespace std;#define MAX 28int tuopu[MAX][MAX],retuopu[MAX][MAX],alpha[MAX],judge[MAX];vector<int> Exist,res;void compare(string s1,string s2){if(s1==s2) return;int i;for(i=0;i<s1.length() && i<s2.length();i++)if(s1[i]!=s2[i]) { tuopu[s2[i]-'A'][s1[i]-'A']=1;//出度retuopu[s1[i]-'A'][s2[i]-'A']=1;//入度,用于删除出度用break; }}int main(){int i,j;vector<string> v;string s;memset(tuopu,0,sizeof(tuopu));memset(alpha,0,sizeof(alpha));memset(judge,0,sizeof(judge));int jishu=0;//记录需要处理的字母的总个数while(cin>>s && s!="#")//输入全部的字符串并把出现过的字母记录下来{v.push_back(s);for(i=0;i<s.length();i++)if(alpha[s[i]-'A']==0) { alpha[s[i]-'A']=1;Exist.push_back(s[i]-'A'); jishu++;}}for(i=0;i<v.size();i++)//建立拓扑排序的图for(j=i+1;j<v.size();j++)compare(v[i],v[j]);while(res.size()<jishu){for(i=0;i<Exist.size();i++){if(judge[Exist[i]]) continue;//这个点已经处理了,跳过int jjudge=0;//判断出度是否为0for(j=0;j<Exist.size();j++){if(tuopu[Exist[i]][Exist[j]]!=0) {jjudge=1;break;}}if(!jjudge)//出度为0{res.push_back(Exist[i]);//将其推入输出向量for(j=0;j<Exist.size();j++){if(retuopu[Exist[i]][Exist[j]])tuopu[Exist[j]][Exist[i]]=0;//删除所有和这个点有关的入度}judge[Exist[i]]=1;//标记该点,设为已处理过}}}for(i=0;i<res.size();i++)printf("%c",res[i]+'A');printf("\n");//system("pause");}


 

原创粉丝点击