题目地址:http://www.fjutacm.com/Problem.jsp?pid=1516
题目:
用小于号"<"来定义两元素之间的关系,并于一个没有重复元素的有序上升序列 从小到大地排列这些元素。
比如说,序列A,B,C,D意味着A在这个问题里,我们会给你一组形如"A
View Code
View Code
比如说,序列A,B,C,D意味着A在这个问题里,我们会给你一组形如"A
输入
输入有多组数据。
每一组数据由其第一行的2个正整数n,m开始。
第一个正整数n代表有n个元素需要排序(2<=n<=26),这些元素一定是按照字母表顺序,从第一个字母(A)开始的n个大写字母。
第二个正整数m代表有m个关系将会在这组数据中被给出。
接下来有m行输入,每一行输入包含3个字符:一个大写字母,一个"<"符号,另一个大写字母。
所有输入的字母不会超出n规定下的,字母表中的字母范围。
当输入的n=m=0时,代表输入结束。
每一组数据由其第一行的2个正整数n,m开始。
第一个正整数n代表有n个元素需要排序(2<=n<=26),这些元素一定是按照字母表顺序,从第一个字母(A)开始的n个大写字母。
第二个正整数m代表有m个关系将会在这组数据中被给出。
接下来有m行输入,每一行输入包含3个字符:一个大写字母,一个"<"符号,另一个大写字母。
所有输入的字母不会超出n规定下的,字母表中的字母范围。
当输入的n=m=0时,代表输入结束。
输出
对于每一组数据,输出有一行。输出必须也必定是以下三种情况之一:
Sorted sequence determined after X relations: YYYY.
[友情翻译:有序序列在给出X个条件后可以成立: YYYY.]
Sorted sequence cannot be determined.
[友情翻译:无法建立有序序列]
Inconsistency found after X relations.
[友情翻译:在给出X个关系后出现矛盾]
Sorted sequence determined after X relations: YYYY.
[友情翻译:有序序列在给出X个条件后可以成立: YYYY.]
Sorted sequence cannot be determined.
[友情翻译:无法建立有序序列]
Inconsistency found after X relations.
[友情翻译:在给出X个关系后出现矛盾]
X是一个整数。
YYYY是当前条件下的有序数列,之间没有分隔符与空格。
YYYY是当前条件下的有序数列,之间没有分隔符与空格。
样例输入
4 6
AABCBA3 2
AB26 1
A0 0
AA
AB26 1
A
样例输出
Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.
一开始题目就看的不是很懂,从 https://blog.csdn.net/weixin_43987810/article/details/96021102这里看了题目的翻译搞懂。
题目其他比较正常,主要是需要求到给出的第几个关系可以求出序列或者出现矛盾,所以就需要每次输入一个关系就运算一次。
网上找的代码都是直接用数组做的,我习惯用vector和queue,就自己写篇博客记一下。
用数组做的:
1 #include2 #include<string.h> 3 using namespace std; 4 5 int map[30][30]; //map标记是否有关系 6 int in[30],n,m; //in为入度 7 int ans[30]; //储存答案序列 8 int Tp() 9 { 10 int temp[30]; //展示存放入度 11 int num; //num表示零入度定点数 12 int pos; //存放零入度定点 13 int cnt=0; 14 int flag=1; //flag=1表示有序,flag=-1表示条件不足 15 for(int i=1;i<=n;i++) 16 temp[i]=in[i]; //备份 17 for(int i=1;i<=n;i++) //需要全图遍历 18 { 19 num=0; 20 for(int j=1;j<=n;j++) 21 { 22 if(temp[j]==0) //入度为0 23 { 24 num++; //零入度点+1 25 pos=j; //存放零入度点 26 } 27 } 28 if(num==0) //无零入度点则有环 29 return 0; 30 else if(num>1) //零入度点不止一个则条件不足 31 flag=-1; 32 temp[pos]=-1; //令此零入度点入度为-1,后面就不找他了 33 ans[cnt++]=pos; //把这个点插入答案序列里 34 for(int j=1;j<=n;j++) 35 { 36 if(map[pos][j]) //他的小弟都入度-1 37 temp[j]--; 38 } 39 } 40 return flag; 41 } 42 int main(void) 43 { 44 while(~scanf("%d %d",&n,&m)) 45 { 46 if(n==0&&m==0) break; 47 memset(map,0,sizeof(map)); 48 memset(in,0,sizeof(in)); 49 int ok=0; 50 for(int i=1;i<=m;i++) 51 { 52 char s[5]; 53 scanf("%s",&s); 54 if(ok) continue; //已经完成就continue 55 int a=s[0]-64,b=s[2]-64; 56 map[a][b]=1; //标记 57 in[b]++; //b入度+1 58 int flag=Tp(); 59 if(flag==0) //flag=0表示矛盾了 60 { 61 printf("Inconsistency found after %d relations.\n",i); 62 ok=1; //得到答案就ok=1 63 } 64 else if(flag==1) //flag=1表示序列已经成立了,输出序列 65 { 66 printf("Sorted sequence determined after %d relations: ",i); 67 for(int j=0;j ) 68 printf("%c",ans[j]+64); 69 printf(".\n"); 70 ok=1; //得到答案就ok=1 71 } 72 } 73 if(!ok) //如果不矛盾也没答案,就输出这个 74 { 75 printf("Sorted sequence cannot be determined.\n"); 76 } 77 } 78 return 0; 79 }
用vector和queue做的:
1 #include2 #include 3 #include 4 #include<string.h> 5 using namespace std; 6 7 int in[30],n,m; //in存入度 8 vector<int> head[30]; //存与该点有关的小弟 9 vector<int> ans; 10 int Tp() 11 { 12 queue<int> q; //定义一个队列暂存序列 13 ans.clear(); //清空ans 14 int flag=1; //flag=1表示有序,flag=-1表示条件不足 15 int temp[30]; //暂时存放入度 16 for(int i=1;i<=n;i++) 17 temp[i]=in[i]; //备份 18 for(int i=1;i<=n;i++) 19 { 20 if(temp[i]==0) //寻找零入度点并插入队列 21 q.push(i); 22 } 23 while(!q.empty()) //把队列里的点放入ans 24 { 25 if(q.size()>1) //如果q队列里的点不止一个,说明条件不足 26 flag=-1; //令flag=-1,但不能直接return ,因为还要继续判断是否矛盾了 27 int x=q.front(); //拿出队列中的点 28 q.pop(); //队列中删去 29 ans.push_back(x); //存入ans 30 for(int j=0;j//遍历与该店有关的小弟 31 { 32 if(--temp[head[x][j]]==0) //令其入度-1并判断之后是否为零,是插入队列中 33 q.push(head[x][j]); 34 } 35 } 36 if(ans.size()!=n) //若ans中的点不足n,则表示有环,关系矛盾了 37 return 0; 38 return flag; 39 } 40 41 int main(void) 42 { 43 while(~scanf("%d %d",&n,&m)) 44 { 45 if(n==0&&m==0) break; 46 47 int ok=0; //该清空的都清空一下 48 memset(in,0,sizeof(in)); 49 for(int i=1;i<=n;i++) 50 head[i].clear(); //这个忘了清wa了一次 51 52 for(int i=1;i<=m;i++) 53 { 54 char s[5]; 55 scanf("%s",s); 56 if(ok) continue; //已经完成就continue 57 int a=s[0]-64,b=s[2]-64; 58 head[a].push_back(b); //存一下a点的小弟 59 in[b]++; //b入度+1 60 61 int flag=Tp(); 62 if(flag==0) //有环 63 { 64 printf("Inconsistency found after %d relations.\n",i); 65 ok=1; 66 } 67 else if(flag==1) //得到有序答案了 68 { 69 printf("Sorted sequence determined after %d relations: ",i); 70 for(int j=0;j ) 71 printf("%c",ans[j]+64); 72 printf(".\n"); 73 ok=1; 74 } 75 } 76 if(!ok) //如果不矛盾也没答案,就输出条件不够 77 printf("Sorted sequence cannot be determined.\n"); 78 } 79 return 0; 80 }