A - Dictionary
Time limit : 20sec / Memory limit : 256MB
Problem Statement
We found a dictionary of the Ancient Civilization Mayo (ACM) during excavation of the ruins. After analysis of the dictionary, we revealed they used a language that had not more than 26 letters. So one of us mapped each letter to a different English alphabet and typed all the words in the dictionary into a computer.
How the words are ordered in the dictionary, especially whether they are ordered lexicographically, is an interesting topic to many people. As a good programmer, you are requested to write a program to judge whether we can consider the words to be sorted in a lexicographical order.
Note: In a lexicographical order, a word always precedes other words it is a prefix of. For example, ab precedes abc, abde, and so on.
Input
The input consists of multiple datasets. Each dataset is formatted as follows:
n
string1
…
stringn
Each dataset consists of n+1 lines. The first line of each dataset contains an integer that indicates n (1≤n≤500). The i-th line of the following n lines contains stringi, which consists of up to 10 English lowercase letters.
The end of the input is 0, and this should not be processed.
Output
Print either yes or no in a line for each dataset, in the order of the input. If all words in the dataset can be considered to be ordered lexicographically, print yes. Otherwise, print no.
Sample Input
4
cba
cab
b
a
3
bca
ab
a
5
abc
acb
b
c
c
5
abc
acb
c
b
b
0
Output for the Sample Input
yes
no
yes
no
Source name
JAG Practice Contest for ACM-ICPC Asia Regional 2012
题意:给你n个字符串,让你判断这些单词是否属于一种顺序(自行定义)
这一看就是一道拓扑排序裸题,但我们今天要讲一讲别的算法
解析:
先读入,判断Si]和S[i+1]在哪里不相同,
我们那Sample Input 1 的第一个举例
4
cba
cab
b
a
a数组表示i字符在字典中是排在j之前(1)还是之后(0)
初始都为0
首先判断S[1]和S[2],在第2位不同,a[‘b’][‘a’]=1
判断S[2]和S[3],第1位不同,a[‘c’][‘a’]=1
同理 a[‘b][‘a’]=1
之后跑floyd。
如果 a[i][i]=1,即出现环 out “no”
else out “yes” ;
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <bitset>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <string>
#include <functional>
using namespace std ;
const int eps=1e-6 ;
const int inf=0x3f3f3f3f ;
#define mp make_pair
#define pb push_back
#define first fi
#define second se
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define REP(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
typedef unsigned long long ull ;
typedef long long ll ;
const int N = 510 ;
const int L = 20 ;
int n ;
char str[N][L] ;
int len[N],G[N][N] ;
int main(){
while (scanf("%d",&n)!=EOF && n!=0){
rep(i,1,n){
scanf("%s",str[i]);
len[i]=strlen(str[i]) ;
}
memset(G,0,sizeof(G)) ;
int ans=1 ;
rep(i,1,n-1){
int j=0 ;
while (j<len[i] && j<len[i+1] && str[i][j]==str[i+1][j]) j++ ;
if (j<len[i] && j==len[i+1]){
ans=0 ;
break ;
}
if (j<len[i] && j<len[i+1]) G[str[i][j]-'a'][str[i+1][j]-'a']=1 ;
}
rep(k,0,26) rep(i,0,26) rep(j,0,26) G[i][j]|=(G[i][k]&G[k][j]) ;
rep(i,0,26) if (G[i][i]) ans=0;
printf("%s\n",ans?"yes":"no") ;
}
return 0 ;
}
#include <iostream>
#include <cstring>
using namespace std;
int n;
string s[505];
bool f[30][30];
bool fulfill(string a,string b)
{
int mn=min(a.size(),b.size());
for (int i=0;i<mn;++i) if (a[i]!=b[i]) return f[a[i]-'a'][b[i]-'a']=true;
if (a.size()>b.size()) return false;
return true;
}
int main()
{
while (cin>>n && n)
{
memset(f,0,sizeof(f));
for (int i=0;i<n;++i) cin>>s[i];
for (int i=0;i<n-1;++i)
{
if (!fulfill(s[i],s[i+1]))
{
cout<<"no\n";
goto ends;
}
}
for (int k=0;k<30;++k) for (int i=0;i<30;++i) for (int j=0;j<30;++j) f[i][j]=f[i][j]|(f[i][k]&f[k][j]);
for (int i=0;i<30;++i) for (int j=0;j<30;++j) if (f[i][j] && f[j][i])
{
cout<<"no\n";
goto ends;
}
cout<<"yes\n";
ends:;
}
return 0;
}