• 7-15 球队“食物链” (30 分)


    某国的足球联赛中有N支参赛球队,编号从1至N。联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场。

    联赛战罢,结果已经尘埃落定。此时,联赛主席突发奇想,希望从中找出一条包含所有球队的“食物链”,来说明联赛的精彩程度。“食物链”为一个1至N的排列{ T1​​ T2​​ ⋯ TN​​ },满足:球队T1​​战胜过球队T2​​,球队T2​​战胜过球队T3​​,⋯,球队T(N1)​​战胜过球队TN​​,球队TN​​战胜过球队T1​​。

    现在主席请你从联赛结果中找出“食物链”。若存在多条“食物链”,请找出字典序最小的。

    注:排列{ a1​​ a2​​ ⋯ aN​​}在字典序上小于排列{ b1​​ b2​​⋯ bN​​ },当且仅当存在整数K(1KN),满足:aK​​<bK​​且对于任意小于K的正整数i,ai​​=bi​​。

    输入格式:

    输入第一行给出一个整数N(2N20),为参赛球队数。随后N行,每行N个字符,给出了N×N的联赛结果表,其中第i行第j列的字符为球队i在主场对阵球队j的比赛结果:W表示球队i战胜球队j,L表示球队i负于球队j,D表示两队打平,-表示无效(当i=j时)。输入中无多余空格。

    输出格式:

    按题目要求找到“食物链”T1​​ T2​​ ⋯ TN​​,将这N个数依次输出在一行上,数字间以1个空格分隔,行的首尾不得有多余空格。若不存在“食物链”,输出“No Solution”。

    输入样例1:

    5
    -LWDW
    W-LDW
    WW-LW
    DWW-W
    DDLW-
    

    输出样例1:

    1 3 5 4 2
    

    输入样例2:

    5
    -WDDW
    D-DWL
    DD-DW
    DDW-D
    DDDD-
    

    输出样例2:

    "No Solution"

    题意:输出一条包含所有队伍且去重的最小字典序的球队T(N1)​​战胜过球队TN​​,球队TN​​战胜过球队T1的集合,输入时'W'表示i(行)队赢了j(列)队,'L'表示j(列)队赢了i(行)队,若找的到则输出,否则输出“No Solution”。

    注意:1,
    此题要求“食物链”包含所有球队,因此此链长度为n。

              2,此题要求“食物链”输出字典序最小的,而搜索按升序搜索,因此只需输出第一个即可满足最小字典序的条件
              3,判断下一步是否能走,若不能则返回,若不加这步会超时
              4,标记用一维数组是因为每支队伍在链中有且只有出现一次
              5,注意这里可能要建立双向边
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int amn=1e2+5;
     6 int a[amn][amn],mp[amn],ans[amn];
     7 char in[amn];
     8 int n,f=0;
     9 void s(int i,int len)
    10 {
    11     if(f)return;
    12     ans[len]=i;
    13     if(len==n)///此题要求“食物链”包含所有球队,因此此链长度为n
    14     {
    15         if(a[i][1])///此题要求“食物链”输出字典序最小的,而搜索按升序搜索,因此只需输出第一个即可满足最小字典序的条件
    16             f=1;
    17         return;
    18     }
    19     ///判断下一步是否能走,若不能则返回,若不加这步会超时
    20     int cn=0;
    21     for(int p=1; p<=n; p++)
    22     {
    23         if(mp[p]==0&&a[p][1]==1)
    24             cn=1;
    25     }
    26     if(cn==0) return;
    27     for(int k=1; k<=n; k++)
    28     {
    29         ///如果当前存在下一步且下一步能走,则继续搜索
    30         if(a[i][k]==1&&mp[k]==0)mp[i]=1,s(k,len+1),mp[i]=0;///标记当前节点,回溯后清除标记,标记用一维数组是因为每支队伍在链中有且只有出现一次
    31     }
    32 }
    33 int main()
    34 {
    35 
    36     while(cin>>n)
    37     {
    38         memset(a,0,sizeof(a));
    39         for(int i=1; i<=n; i++)
    40         {
    41             ans[i]=amn;
    42             mp[i]=0;
    43             scanf("%s",in+1);
    44             for(int j=1; j<=n; j++)
    45             {
    46                 if(in[j]=='W')a[i][j]=1;///注意这里可能要建立双向边
    47                 if(in[j]=='L')a[j][i]=1;
    48             }
    49         }
    50         f=0;
    51         s(1,1);
    52         if(f)
    53         {
    54             for(int i=1; i<=n; i++)
    55             {
    56                 cout<<ans[i];
    57                 if(i<n)cout<<" ";
    58                 else cout<<endl;
    59             }
    60         }
    61         else
    62         {
    63             cout<<"No Solution
    ";
    64         }
    65 
    66     }
    67 }
     
  • 相关阅读:
    币值转换
    打印沙漏
    秋季学期总结
    在人生道路上对我影响最大一位老师
    自我介绍
    python笔记十五(面向对象及其特性)
    python笔记十四(高阶函数——map/reduce、filter、sorted)
    python笔记十三(高阶函数、装饰器)
    python笔记十二(匿名函数)
    Python笔记十一(迭代器)
  • 原文地址:https://www.cnblogs.com/Railgun000/p/10526135.html
Copyright © 2020-2023  润新知