题目来源:http://codeforces.com/gym/101485/attachments
二分图匹配+离散化。
WA了好多发:
1.‘+’、‘*’运算得到的结果可能相同,不要忘了加else。
2.数据会爆int,一定要用long long
匈牙利算法进行二分图匹配。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=9510;
int n,cnt,from[maxn*3];
ll a[maxn],b[maxn],ans[maxn];
map<ll,ll> m,p;
vector<int> v[maxn];
bool vis[maxn*3];
bool match(int x) {
for (int i = 0; i < v[x].size(); ++i) {
if (vis[v[x][i]] == 0) {
vis[v[x][i]] = 1;
if (from[v[x][i]] == -1 || match(from[v[x][i]])) {
from[v[x][i]] = x;
return 1;
}
}
}
return 0;
}
bool hungry() {
memset(from, -1, sizeof(from));
for (int i = 1; i <= n; ++i) {
memset(vis, 0, sizeof(vis));
if (!match(i))return 0;
}
return 1;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%lld%lld", &a[i], &b[i]);
ll x = a[i] + b[i];
if (m.count(x) == 0) {
++cnt;
m[x] = cnt;
p[cnt] = x;
}
v[i].push_back(m[x]);
x = a[i] - b[i];
if (m.count(x) == 0) {
++cnt;
m[x] = cnt;
p[cnt] = x;
}
v[i].push_back(m[x]);
x = a[i] * b[i];
if (m.count(x) == 0) {
++cnt;
m[x] = cnt;
p[cnt] = x;
}
v[i].push_back(m[x]);
}
if (!hungry()) {
printf("impossible\n");
return 0;
}
for (int i = 1; i <= cnt; ++i) {
if (from[i] != -1) {
ans[from[i]] = p[i];
}
}
for (int i = 1; i <= n; ++i) {
printf("%lld ", a[i]);
if (a[i] + b[i] == ans[i])printf("+");
else if (a[i] - b[i] == ans[i])printf("-");
else if (a[i] * b[i] == ans[i])printf("*");
printf(" %lld = %lld\n", b[i], ans[i]);
}
return 0;
}