A

传送门

题目大意

给你n个字符串,问是否可以通过改变26个字母的排列顺序是这n个字符串的字典序是非降排列的。

分析

我们考虑设相邻两个字符串的第一个不相同字符的位置为j,以为要求字典序不降,所以有第i个字符串的第j位向第i+1个字符串的第j位连边,最后如果没有环则代表可以找到一种顺序,反之不能。

注:代码应用的是floyd判环。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl
#define pb push_back
char s[510][50];
int g[50][50],ok;
int main(){
      int n,m,i,j,k;
      scanf("%d",&n);
      while(n!=0){
          ok=1;
          for(i=1;i<=n;i++)
            scanf("%s",s[i]);
          memset(g,0,sizeof(g));
          for(i=1;i<n;i++){
            int len=strlen(s[i]),len2=strlen(s[i+1]);
            j=0;
            while(j<len&&j<len2&&s[i][j]==s[i+1][j])j++;
            if(j<len&&j==len2){
                ok=0;
                break;
            }
          if(j<len&&j<len2){
            g[s[i][j]-'a'][s[i+1][j]-'a']=1;
          }
        }
        for(k=0;k<26;k++)
          for(i=0;i<26;i++)
            for(j=0;j<26;j++)
              g[i][j]|=(g[i][k]&g[k][j]);
        for(i=0;i<26;i++)
          if(g[i][i])
            ok=0;
        if(ok)puts("yes");
          else puts("no");
        scanf("%d",&n);
      }
      return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/9335696.html