• HRBUST 1162 魔女【DP】


    Description

    平行世界是动漫作品中经常涉及的题材,而且往往这些作品都相当的精彩,如《寒蝉鸣泣之时》、《CLANNAD》、《魔法少女小圆》、《命运石之门》等。世界从诞生到结束,最终又轮回到诞生。无论命运如何的绝对,在无数次的轮回中终将被打破,犹如掷骰子,在无限接近于零但不等于零的机率中往复。这样在无限的反复和轮回中,将其可能性放大到100%。最典型的人物就是《海猫鸣泣之时》中的能无限次引发奇迹力量的“奇迹之魔女”贝伦卡斯泰露。而与此对应的是能够让事件发生的可能性无限接近于零“绝对的魔女”拉姆达戴露塔。在故事中,贝伦的目的是为了令主角战人在黄金魔女的游戏中“赢”,而拉姆达的目的则是为了让游戏永远“平局”下去。
    由于可以无限的轮回,因此可以将整个黄金魔女的游戏看成一个环,在游戏中有n个关键人物。人物之间存在着胜败关系,如果两个人之间发生斗争,实力强的一方会获胜,而实力弱的一方会被击败退出游戏。一开始每个人物只会跟编号排在他后面的人接触,比如人物1会跟人物2之间斗争,人物2会跟人物3斗争,人物n会跟人物1斗争。当人物消失后,胜者就会接触到下一个人物,比如人物1战胜了人物2,人物2退出了游戏,那它就会跟人物3之间产生斗争。各个人物之间的胜败情况是固定的。最终游戏中只会剩下一个人,成为游戏最终的胜者。但是人物不同的战斗顺序,最终胜利的这个人可能不同。
    现在的问题是,在这场“黄金的魔女”设下的棋局中,“绝对的魔女”使得人物与人物的胜败关系是确定的,而“奇迹的魔女”想知道,这场游戏中,都有哪些人是有可能生存下来的。

    Input

    有多组数据,第一行是一个整数n表示事件的数目。(2<=n<=100)
    随后的n行是一个n行n列的矩阵。矩阵中的第i行第j列,如果为1,表示人物i与人物j斗争时人物i会胜利。为0则表示,表示人物i与人物j斗争时人物j会胜利。

    Output

    对于每组测试数据,第一行输出一个k表示有多少个人物可能获胜,接下来的k行每行输出一个人物的编号,编号从小到大输出。

    Sample Input

    3
    0 1 0
    0 0 1
    1 0 0

    2
    0 0
    1 0
    Sample Output

    3
    1
    2
    3
    1
    2

     

    思路:和lrj的例题决斗思路一样,meet[i,j]表示是否有可能i和j相遇, 则第i个人能取得最后的胜利当且仅当meet[i,i]为true.如果i最后能碰到自己,即她能存留下来

    状态转移: 考虑相遇前的最后一步, 则meet[I,j]为true当且仅当–能找到一个k, 使得i能遇k, k能遇到j, 且i或者j能打败k.
    代码如下:

    #include<stdio.h>
    #include<string.h>
    int meet[103][103], d[103][103];
    int main()
    {
    int n, i, t, j, k, mm;
    while(scanf("%d", &n)!=EOF)
    {
    memset(d, 0, sizeof(d));
    memset(meet, 0, sizeof(meet));
    for(i=0; i<n; i++)
    {
    for(j=0; j<n; j++)
    {
    scanf("%d", &mm);
    if(mm==1)
    d[i][j]=1;
    }
    }
    for(i=0; i<n-1; i++)
    meet[i][i+1]=1, meet[i+1][i]=1;
    meet[0][n-1]=1, meet[n-1][0]=1;
    int flag;
    for(t=2; t<=n; t++)
    for(i=0;i<n;i++)
    {
    j=(i+t)%n;
    flag=0;
    for(k=(i+1)%n; k!=j; k=(k+1)%n)
    {
    if(meet[i][k]&&meet[k][j]&&(1==d[i][k]||1==d[j][k]))
    {
    meet[i][j]=1;
    flag=1;
    break;
    }
    }
    if(!flag)
    meet[i][j]=0;
    }
    int num=0;
    for(i=0; i<n; i++)
    if(meet[i][i])
    num++;
    printf("%d\n", num);
    for(i=0; i<n; i++)
    if(meet[i][i])
    printf("%d\n", i+1);
    }
    return 0;
    }

     
  • 相关阅读:
    js,js中使用正则表达式
    web开发中文件下载
    EL表达式
    Servlet Filter
    压缩文件 乱码问题(转载)
    MFC CopyDirectory
    SaveFileDialog
    Create Window
    CDateTimeCtrl 设置时间
    键值表
  • 原文地址:https://www.cnblogs.com/Hilda/p/2616789.html
Copyright © 2020-2023  润新知