思路:
这里n比较小从 0 到 26 ,所以用一般的暴力解法都不会出现问题:
大致思路就是:用合适的方式存储输入的不等式,设存入的不等式有m个,用循环依次遍历使用公式 1~m ,用flord 进行传递闭包处理,处理后检查双重循环遍历关系矩阵d ,看是否存在违规情况:
- 如果检测期间出现了矛盾情况即,d[i][j]=1 , d[j][i] =1;则立刻退出检查,并输出用前 t 个不等式会出现矛盾。
- 如果检测期间没有出现矛盾情况,但使用完所有共识后仍有一种情况出现:d[ i ] [ j ] =0 , d[ j ] [ i ] =0,说明还不能确定i,j之间的关系,并输出用前 t 个不等式不能确定所有字符的关系。
- 如果检测完毕后,上述1,2两种情况都没出现就输出成功。
code:
#include <bits/stdc++.h>
#include <string.h>
#include <map>
#include <stack>
#include <queue>
using namespace std;
const int maxn=350+10;
const int INF=0x7fffffff;
typedef pair<int ,int > PII;
int d[maxn][maxn];
int n,m;
char a[10];
typedef pair<int , int > PII;
PII g[maxn];
map<char , int > mp;
vector<char> seq;
int res;
void Flord(){
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
d[i][j] |=d[i][k]&d[k][j];
}
}
}
bool cmp(char a,char b){
if(d[mp[a]][mp[b]]==1) return true;
return false;
}
int main(){
int x,y;
while(cin>>n>>m && (n!=0 || m!=0)){
bool flag1=false,flag2=false;
//创建两个flag 进行标志,flag1标志是否出现矛盾,flag2标志是否出现无解的情况。
mp.clear(),seq.clear();
fill(d[0],d[0]+maxn*maxn,0);
res=0;
for(int i=1;i<=m;i++){
scanf("%s",a);
if(mp.count(a[0])) x=mp[a[0]]; // 用map存储输入不等式的字符和位置下标的hash关系
else { seq.push_back(a[0]);x=seq.size();mp.insert({a[0],x});} //如果之前有存过字符a[0] 就返回它的下标
if(mp.count(a[2])) y=mp[a[2]];
else { seq.push_back(a[2]);y=seq.size();mp.insert({a[2],y});}
g[i].first=x,g[i].second=y; //g[i] 存储第i条不等式两字符对应的位置下标
}
for(int t=1;t<=m;t++){
flag2=false;
for(int j=1;j<=t;j++){
d[g[j].first][g[j].second]=1;
}
Flord();
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(d[i][j]==1 && d[j][i]==1) {
cout<<"Inconsistency found after "<<t<<" relations."<<endl;
flag1=true;
break;
}
else if( d[i][j]==0 && d[j][i]==0){
flag2=true;
}
}
if(flag1) break;
}
if(flag1) break;
if(!flag1 && !flag2) {
res=t;
break;
}
}
if(!flag1 && !flag2) {
sort(seq.begin(),seq.end(),cmp);
cout<<"Sorted sequence determined after "<<res<<" relations: ";
for(int i=0;i<seq.size();i++) cout<<seq[i];
cout<<"."<<endl;
}
if(!flag1 && flag2) cout<<"Sorted sequence cannot be determined."<<endl;
}
system("pause");
return 0;
}
// 用map<char ,int >存输入的字符对应位置序号
//vecter<char> 存前n个出现的不同字符,成功时候sort一下输出