码迷,mamicode.com
首页 > 其他好文 > 详细

[SCOI2008]天平

时间:2018-02-23 17:12:20      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:reg   大小   algorithm   -o   字符   sam   整数   main   badge   

题目背景

2008四川NOI省选

题目描述

你有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

暴力:25

用拓扑排序确定每个点的重量,然后暴力枚举哪两个点。

但是拓扑序不确定,题目要求确定才能统计,所以WA+T+A

正解:

差分约束。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=60;
 7 int Max[N][N],Min[N][N];
 8 char s[N];
 9 int n,A,B,c1,c2,c3;
10 void Floyd()
11 {
12    for(int k=1;k<=n;k++)
13     for(int i=1;i<=n;i++)
14      for(int j=1;j<=n;j++)
15       if(i!=k && i!=j && k!=j)
16       {
17         Max[i][j]=min(Max[i][j],Max[i][k]+Max[k][j]);
18         Min[i][j]=max(Min[i][j],Min[i][k]+Min[k][j]);
19       }
20 }
21 void work()
22 {
23   for(int i=1;i<=n;i++)
24    for(int j=1;j<i;j++)
25     if(i!=A && i!=B && j!=A && j!=B)
26     {
27         if(Min[A][i]>Max[j][B] || Min[A][j]>Max[i][B])c1++;
28         if(Max[A][i]<Min[j][B] || Max[B][i]<Min[j][A])c3++;
29         if(Max[A][i]==Min[A][i] && Max[j][B]==Min[j][B] && Max[A][i]==Max[j][B]) c2++;
30         else if(Max[A][j]==Min[A][j] && Max[i][B]==Min[i][B] && Max[A][j]==Max[i][B]) c2++;
31     }
32    printf("%d %d %d",c1,c2,c3);
33 }
34 int main()
35 {
36     scanf("%d%d%d",&n,&A,&B);
37     for(int i=1;i<=n;i++)
38     {
39        scanf("%s",s+1);
40        for(int j=1;j<=n;j++)
41        {
42          if(s[j]===||i==j+1) Max[i][j]=0,Min[i][j]=0;
43          if(s[j]==+) Max[i][j]=2,Min[i][j]=1;
44          if(s[j]==-) Max[i][j]=-1,Min[i][j]=-2;
45          if(s[j]==?)Max[i][j]=2,Min[i][j]=-2;
46        }    
47     }
48     Floyd();
49     work();
50    return 0;
51 }

死亡是最简单不过的事情,但真正困难的是光荣的活下去。

[SCOI2008]天平

标签:reg   大小   algorithm   -o   字符   sam   整数   main   badge   

原文地址:https://www.cnblogs.com/adelalove/p/8462497.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!