zoukankan      html  css  js  c++  java
  • [SCOI2008]天平

    题目描述

    你有n个砝码,均为1克,2克或者3克。你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系。你把其中两个砝码A 和B 放在天平的左边,需要另外选出两个砝码放在天平的右边。问:有多少种选法使得天平的左边重(c1)、一样重(c2)、右边重(c3)?(只有结果保证惟一 的选法才统计在内)

    输入输出格式

    输入格式:

    第一行包含三个正整数n,A,B(1<=A,B<=N,A 和B 不相等)。砝码编号

    为1~N。以下n行包含重量关系矩阵,其中第i行第j个字符为加号“+”表示砝

    码i比砝码j重,减号“-”表示砝码i比砝码j 轻,等号“=”表示砝码i和砝码

    j一样重,问号“?”表示二者的关系未知。存在一种情况符合该矩阵。

    输出格式:

    仅一行,包含三个整数,即c1,c2和c3。

    输入输出样例

    输入样例#1: 复制
    6 2 5
    ?+????
    -?+???
    ?-????
    ????+?
    ???-?+
    ????-?
    输出样例#1: 复制
    1 4 1
    输入样例#2: 复制
    14 8 4
    ?+???++?????++
    -??=?=???????=
    ??????????=???
    ?=??+?==??????
    ???-???-???-??
    -=????????????
    -??=???=?-+???
    ???=+?=???????
    ??????????????
    ??????+???????
    ??=???-????-??
    ????+?????+???
    -?????????????
    -=????????????
    输出样例#2: 复制
    18 12 11

    说明

    4<=n<=50

    A+B>C+D <=> A-C>D-B 由此我们可以使用差分约束

    用数组Max[i][j],Min[i][j]分别表示 i-j 的最大值和最小值,使用Floyd

    对这个数组用Floyd,就可以求出最终两点间的大小关系

    Max[i][j]=min(Max[i][j],Max[i][k]+Max[k][j])

    Min[i][j]=max(Min[i][j],Min[i][k]+Min[k][j])

    拿Max来说明:比如i-j<=2,i-k<=1,k-j<=0

    那么显然i-j条件就变成i-j<=1

    于是判断就可以枚举两个砝码

    如果Min[s1][i]>Max[j][s2]那么显然大小关系是确定的

    就有s1-i>j-s2   =>   s1+s2>i+j  于是c1可以+1

    c2和c3同理

    zyys(贼有意思)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 int Max[51][51],Min[51][51];
     7 char s[51];
     8 int n,s1,s2,c1,c2,c3;
     9 int main()
    10 {int i,j,k,l;
    11   cin>>n>>s1>>s2;
    12   for (i=1;i<=n;i++)
    13     {
    14       scanf("%s",s);
    15       l=strlen(s);
    16       for (j=0;j<l;j++)
    17     {
    18       if (s[j]=='='||i==j+1)
    19         Max[i][j+1]=0,Min[i][j+1]=0;
    20       else 
    21       if (s[j]=='+')
    22         Max[i][j+1]=2,Min[i][j+1]=1;
    23       else 
    24       if (s[j]=='-')
    25         Max[i][j+1]=-1,Min[i][j+1]=-2;
    26       else 
    27       if (s[j]=='?')
    28         Max[i][j+1]=2,Min[i][j+1]=-2;
    29     }    
    30     }
    31   for (k=1;k<=n;k++)
    32     for (i=1;i<=n;i++)
    33       if (i!=k)
    34     {
    35       for (j=1;j<=n;j++)
    36         if (i!=j&&k!=j)
    37           {
    38         Max[i][j]=min(Max[i][j],Max[i][k]+Max[k][j]);
    39         Min[i][j]=max(Min[i][j],Min[i][k]+Min[k][j]);
    40           }
    41       }
    42   for (i=1;i<=n;i++)
    43     if (i!=s1&&i!=s2)
    44       {
    45     for (j=1;j<i;j++)
    46       if (j!=s1&&j!=s2)
    47         {
    48           if (Min[s1][i]>Max[j][s2]||Min[s1][j]>Max[i][s2])
    49         c1++;
    50           if (Max[s1][i]<Min[j][s2]||Max[s2][i]<Min[j][s1])
    51         c3++;
    52           if ((Max[s1][i]==Min[s1][i]&&Max[j][s2]==Min[j][s2]&&Max[s1][i]==Max[j][s2])||(Max[s1][j]==Min[s1][j]&&Max[i][s2]==Min[i][s2]&&Max[s1][j]==Max[i][s2])) c2++;
    53         }
    54       }
    55   cout<<c1<<' '<<c2<<' '<<c3;
    56 }
  • 相关阅读:
    LeetCode "Group Shifted Strings"
    LeetCode "Read N Characters Given Read4 II
    LeetCode "Factor Combinations"
    LeetCode "Paint House II"
    LeetCode "Shortest Word Distance II"
    LeetCode "Flatten 2D Vector"
    LeetCode "Meeting Rooms II"
    iOS开发UI篇—UITableview控件使用小结
    ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
    iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7745285.html
Copyright © 2011-2022 走看看