題目描述
有N名士兵(1<=N<=26),編號依次爲A,B,C,……進行隊列訓練時,指揮官要把一些士兵從高到矮依次排成一行,但現在指揮官不能直接獲得每個士兵的身高信息,只能獲得“P1比P2高”這樣的比較結果(P1,P2∈{A,B,…Z},記爲P1>P2),如“A>B”表示A比B高。
編一程序,根據所得到的比較結果求出符合條件的排隊方案。
注:比較結果中沒有涉及到的士兵不參加排隊。
例如,設有3個士兵,A、B、C,給出關係(A,B),(B,C)。其中(A,B)表示士兵A高於B,當上面的關係給出之後,可以將他們排成一隊:ABC。
輸入輸出格式
輸入格式:
輸入文件中每個比較結果在文件中佔一行。
輸出格式:
若輸入數據無解或不能唯一確定,則輸出“NO ANSWER!”,否則從高到矮依次輸出每一個士兵的編號,中間無分隔符,並把結果寫入文本文件中。
輸入輸出樣例
輸入樣例#1:
A>B
B>F
F>D
這道題目看上去十分的困難,感覺毫無頭緒,但是有經驗的OI選手一眼就可以看出,這是TOP排序啊!(若不知道TOP排序,請見『這裏!』)。但是在簡單的Top排序上又要加入一些判斷,詳情見代碼:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<iostream>
using namespace std;
const int Inf=2147483647;
struct node{
int u,v,w;
}e[100010];
int f[100010];
int b[27],g[27][27],in[27],ans[27];
long long gl(){
char c=getchar();long long f=1;
int sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
void out(int all){
for(int i=1;i<=all;i++)
printf("%c",ans[i]+'A'-1);
puts("");
}
int main(){
int i,j,k,n,m;
char c,d,o;
int all=0;
while(cin>>c>>o>>d){
int p=c-'A'+1,q=d-'A'+1;
g[p][q]=1;in[q]++;
if(!b[p])all++;//這裏是統計總字母個數
if(!b[q])all++;
b[p]=1;b[q]=1;//這裏是爲了後一步
}
for(i=1;i<=26;i++)
if(!b[i])in[i]=Inf;//這裏是表示某一個點爲了不使它進入TOP序列,把他們的初值設爲∞
n=26;
i=0;
do{
i++;j=1;
int flag=0;
while(j<=n && in[j])j++;
if(j>n)break;
for(k=j+1;k<=n;k++)
if(in[k]==0){
flag=1;break;//這個是爲了判斷答案是否爲1
}
if(flag)break;
ans[i]=j;in[j]=1;
for(k=1;k<=n;k++)
if(g[j][k])in[k]--;
}while(i<all && j<=n);
if(i<all || j>n)printf("NO ANSWER!\n");
else out(all);
return 0;
}
整個代碼簡潔明瞭,一道難題瞬間水過!!!╰(°▽°)╯