zoukankan      html  css  js  c++  java
  • fzu Problem

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2232

    Description

    GG学长虽然并不打炉石传说,但是由于题面需要他便学会了打炉石传说。但是传统的炉石传说对于刚入门的GG学长来说有点复杂,所以他决定自己开发一个简化版的炉石传说。

     

    在简化版的炉石传说中:

    每个随从只有生命值和攻击力,并且在你的回合下,你的每只随从在本回合下只能选择一个敌方随从进行攻击。当两个随从a,b交战时,a的生命值将减去b的攻击力,b的生命值将减去a的攻击力,(两个伤害没有先后顺序,同时结算)。如果a或b的生命值不大于0,该随从将死亡。

     

    某一次对局中,GG学长和对手场面上均有n个随从,并且是GG学长的回合。由于GG学长是个固执的boy,他一定要在本回合杀死对方所有随从,并且保证自己的随从全部存活。他想知道能否做到。

    Input

    第一行为T,表示有T组数据。T<=100。

    每组数据第一行为n,表示随从数量(1 <= n <= 100)

    接下来一行2 * n个数字a1, b1, a2, b2, ... , an, bn (1 <= ai, bi <= 100)

    表示GG学长的n个随从,ai表示随从生命,bi表示随从攻击力

    接下来一行2 * n个数字c1, d1, c2, d2, ... , cn, dn (1 <= ci, di <= 100)

    表示对手的n个随从,ci表示随从生命,di表示随从攻击力。

    Output

    每组数据,根据GG是否能完成他的目标,输出一行”Yes”或”No”。

    Sample Input
    2
    3
    4 4 5 5 6 6
    1 1 2 2 3 3
    3
    4 4 5 5 6 6
    1 4 2 4 3 4
    Sample Output
    Yes
    No

    匈牙利算法:因为是一次性打败对方的所有人,所以要求学长的每个随从都要打败对手的随从,所以可以看成是匹配问题,找到最合适的匹配使得每一对都能符合条件,就是构造一个图,b[i][j] = 1表示学长的第i个随从和对手的第j个随从战斗后,随从i的生命力>0 随从j的生命力<=0,然后找到最大匹配是否是n即可;

    *:第一次写的时候觉得就是简单的数学问题嘛,排好序记录下就好了,结果TLE了,( ▼-▼ ),看题目中范围都才100,真的没想过会超时

    TLE代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #include<stdlib.h>
     7 #include<map>
     8 #include<cmath>
     9 
    10 using namespace std;
    11 
    12 #define N 350
    13 #define INF 0x3f3f3f3f
    14 
    15 
    16 
    17 struct node
    18 {
    19     int s,f,x;
    20 };
    21 
    22 node d[N],g[N];
    23 
    24 bool cmp1(node a,node b)
    25 {
    26     return a.s<b.s;
    27 }
    28 
    29 bool cmp2(node a,node b)
    30 {
    31     return a.f<b.f;
    32 }
    33 
    34 int main()
    35 {
    36     int T,n,i;
    37 
    38     scanf("%d", &T);
    39 
    40     while(T--)
    41     {
    42         scanf("%d", &n);
    43 
    44         for(i=0; i<n; i++)
    45             scanf("%d %d", &g[i].s, &g[i].f);
    46         for(i=0; i<n; i++)
    47             scanf("%d %d", &d[i].s, &d[i].f);
    48 
    49         sort(g,g+n,cmp1);
    50         sort(d,d+n,cmp2);
    51 
    52         int ans=0;
    53         for(i=0;i<n;i++)
    54         {
    55             while(1)
    56             {
    57                 g[i].x=g[i].s-d[i].f;
    58                 d[i].x=d[i].s-g[i].f;
    59                 if(d[i].x<=0&&g[i].x>0)
    60                 {
    61                      ans++;
    62                      break;
    63                 }
    64                 if(d[i].x<=0||g[i].x<=0)
    65                     break;
    66             }
    67         }
    68 
    69         if(ans==n)
    70             printf("Yes
    ");
    71         else
    72             printf("No
    ");
    73     }
    74     return 0;
    75 }

    既然超时就只好往二分想了,然后就成了匹配题,( ▼-▼ ),二分匹配~~~

    AC代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #include<stdlib.h>
     7 #include<map>
     8 #include<cmath>
     9 
    10 using namespace std;
    11 
    12 #define N 350
    13 #define INF 0x3f3f3f3f
    14 
    15 
    16 int v[N],vis[N],n, b[N][N];
    17 
    18 struct node
    19 {
    20     int s,f;
    21 };
    22 
    23 node d[N],g[N];
    24 
    25 int Find(int s)
    26 {
    27     int i;
    28 
    29     for(i=1;i<=n;i++)
    30     {
    31         if(!v[i]&&b[s][i])
    32         {
    33             v[i]=1;
    34             if(!vis[i]||Find(vis[i]))
    35             {
    36                 vis[i]=s;
    37                 return 1;
    38             }
    39         }
    40     }
    41     return 0;
    42 }
    43 
    44 int main()
    45 {
    46     int T,i,j,x,y;
    47 
    48     scanf("%d", &T);
    49 
    50     while(T--)
    51     {
    52         memset(b,0,sizeof(b));
    53 
    54         scanf("%d", &n);
    55 
    56         for(i=1; i<=n; i++)
    57             scanf("%d %d", &g[i].s, &g[i].f);///GG学长
    58         for(i=1; i<=n; i++)
    59             scanf("%d %d", &d[i].s, &d[i].f);///对手
    60 
    61         for(i=1;i<=n;i++)
    62             for(j=1;j<=n;j++)
    63         {
    64             x=g[i].s-d[j].f;
    65             y=d[j].s-g[i].f;
    66             if(x>0&&y<=0)
    67                 b[i][j]=1;
    68         }
    69 
    70         memset(vis,0,sizeof(vis));
    71         int ans=0;
    72 
    73         for(i=1;i<=n;i++)/**/
    74         {
    75             memset(v,0,sizeof(v));
    76             if(Find(i))
    77                 ans++;
    78         }
    79 
    80         if(ans==n)
    81             printf("Yes
    ");
    82         else
    83             printf("No
    ");
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    [转] 股票基础知识
    [原] combobox如何让用户不能输入只能从下拉列表里面选择
    【原】2个面试问题(与同事李将的交流)
    [转] 纯代码取得本机IP地址
    [转] 关于硬盘修复以及低级格式化的一些文章
    [转] 130道C#面试题
    初学Sockets编程(四) 发送和接收数据
    利用Beyond Compare比较文件
    第三日:SimuLink之后是Stateflow
    简单的RPC编程实践——HelloWorld的实现
  • 原文地址:https://www.cnblogs.com/weiyuan/p/5753863.html
Copyright © 2011-2022 走看看