P2474 [SCOI2008] 天平
Sol
题面只给出了两两之间的大小关系,然后需要你求出如果给定两个砝码 \(A,B\),然后你再挑选两个与 \(A,B\) 不同的砝码放到天平上,问有分别有几种方式天平向左,平衡,向右。
考虑记录两个砝码之间的差的最大值和最小值,分别记作 \(f_{i,j},g_{i,j}\),对于一个途径的 \(k\)(就是 \(i,j\) 都与 \(k\) 这个砝码比较以后得到的结果),\(f_{i,j}\gets_{\min(f_{i,j},\max(f_{i,k},f_{k,j}))}\),\(g\) 同理。
统计答案的时候直接枚举所选的两个砝码,然后注意两个砝码的大小之差有没有交集即可。
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
#define debug(x) cerr << #x << ' ' << x << endl
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
if (y > x) return x = y,true;
return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
if (y < x) return x = y,true;
return false;
}
LL power (LL a,LL b,LL p) {
if (!a) return 0;
LL ans = 1;
while (b) {
if (b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 60;
int n,a,b;
int f[N][N],g[N][N];
void mian () {
cin >> n >> a >> b;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
char ch;
cin >> ch;
if (i == j && ch == '=') f[i][j] = g[i][j] = 0;
else if (ch == '+') f[i][j] = 2,g[i][j] = 1;
else if (ch == '-') f[i][j] = -1,g[i][j] = -2;
else if (ch == '?') f[i][j] = 2,g[i][j] = -2;
}
}
for (int k = 1;k <= n;k++) {
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
tomin (f[i][j],f[i][k] + f[k][j]);
tomax (g[i][j],g[i][k] + g[k][j]);
}
}
}
int ans1 = 0,ans2 = 0,ans3 = 0;
for (int i = 1;i <= n;i++) {
for (int j = 1;j < i;j++) {
if (i == a || i == b || j == a || j == b) continue;
if (g[a][i] > f[j][b] || g[a][j] > f[i][b]) ans1++;
if (g[a][i] == f[a][i] && g[a][i] == g[j][b] && g[j][b] == f[j][b]) ans2++;
else if (g[b][i] == f[b][i] && g[b][i] == g[j][a] && g[j][a] == f[j][a]) ans2++;
if (f[a][i] < g[j][b] || f[a][j] < g[i][b]) ans3++;
}
}
cout << ans1 << ' ' << ans2 << ' ' << ans3 << endl;
}
int main () {
int T = 1;
// cin >> T;
while (T--) mian ();
return 0;
}

浙公网安备 33010602011771号