Sorting It All Out

Problem Description
An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.
 

Input
Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.
 

Output
For each problem instance, output consists of one line. This line should be one of the following three: 

Sorted sequence determined after xxx relations: yyy...y. 
Sorted sequence cannot be determined. 
Inconsistency found after xxx relations. 

where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. 
 

Sample Input
  
  
4 6 A<B A<C B<C C<D B<D A<B 3 2 A<B B<A 26 1 A<Z 0 0
 

Sample Output
  
  
Sorted sequence determined after 4 relations: ABCD. Inconsistency found after 2 relations. Sorted sequence cannot be determined.
 

Source
PKU
 
/*
其他人做这道题用拓扑排序的比较多~~

数据结构刚学……这些题所用到的数据结构还不算是会,不能写好题解,所以,没有写最近做过的题的题解

用一个数组f[j][k]来储存字母j和字母k的关系,用num[j]统计比字母j大的字母数。

每一次输入关系,就需要更新f[j][k],不仅仅是j和k,还有j和k相关的字母的关系。

每个字母每出现一个比它大的字母,num就计一次数。

所以,
如果能确定字母序列的话,N个字母的num值排序后一定是严格递减(递增),排序后相邻的两个字母的num值差值为1;
如果,出现关系冲突,在每一次更新关系之后,肯定出现f[j][k]==1并且f[k][j]==1,此时做个标记,其他的关系就不用看了;
如果,直至最后也无法判断出序列,那N个字母的num值排序后,相邻的两个字母的num值差值不一定都为1。

如下:
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
#define maxn 26

int f[maxn][maxn]= {0};       
int num[maxn]= {0};
char ans[maxn]= {0};         //如果能出现满足条件的,生成序列
int ansf=0;                  //用于表示三种回答,为0时,>0时,<0时。顺便记录到哪一步就已经结果了
int n,m;

int judge(int N)             //作用:1,更新关系;2,判断关系中是否有冲突;3,判断关系是否可以生成序列
{
    for(int i=0; i<N; i++)   //作用1(像不像 Floyd算法 )
        for(int j=0; j<N; j++)
        {
            if(i==j)
                continue;
            for(int k=0; k<N; k++)
            {
                if(i==k||j==k)
                    continue;
                if(f[j][i]&&f[i][k]&&!f[j][k])
                {
                    f[j][k]=1;
                    num[j]++;
                }
            }
        }
    for(int j=0; j<N; j++)           //作用2
        for(int k=0; k<N; k++)
        {
            if(j==k)
                continue;
            if(f[j][k]==1&&f[k][j]==1)
                return -1;
        }
    int temp[maxn]= {0};
    for(int i=0; i<N; i++)
        temp[i]=num[i];
    sort(temp,temp+N);
    for(int i=0; i<N; i++)         //作用3
        if(temp[i]!=i)
            return 0;
    return 1;
}

void  produce(int N)            //生成结果
{
    for(int j=N-1; j>=0; j--)
    {
        for(int k=0; k<N; k++)
            if(num[k]==j)
                ans[N-1-j]=k+'A';
    }
    ans[N]='\0';
}

int main()
{
    while(cin>>n>>m&&!(n==m&&n==0))
    {
        ansf=0;
        memset(f,0,sizeof(f));
        memset(num,0,sizeof(num));
        memset(ans,0,sizeof(ans));
        int flag=0;
        for(int i=0; i<m; i++)
        {
            char str[3]= {0};
            cin>>str;
            if(flag)
                continue;

            int a=str[0]-'A',b=str[2]-'A';
            if(!f[a][b])
            {
                f[a][b]=1;
                num[a]++;
            }

            if(judge(n)==1)
            {
                flag=1;
                produce(n);
                ansf=i+1;
            }
            else if(judge(n)==-1)
            {
                flag=1;
                ansf=-i-1;
            }
        }
        if(ansf>0)             //输出结果
        {
            printf("Sorted sequence determined after %d relations: %s.\n",ansf,ans);
        }
        else if(ansf==0)
        {
            printf("Sorted sequence cannot be determined.\n");
        }
        else
        {
            printf("Inconsistency found after %d relations.\n",-ansf);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值