题目描述
你有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。
输入输出样例
输入样例#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 }