题外话:
vj上的题交到的网站不知道怎么回事数据都炸了。。。还是去交codeforces吧。。
ps:确切的说是交到icpc?网站的都炸了,,
题目链接:
http://codeforces.com/gym/101485
我是用网络流做的,后来听说官方题解是二分图匹配,不过都一样啦。
s连2500个点(容量为1),然后找2500个点分别去连他们能得到的三种数值,然后对于每种数值,连t(容量为1)。跑一遍最大流,如果不等于n(点的个数),那么无解。如果等了那么就去找对应的那条边就好了。
#include <string.h>
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
typedef long long int lli;
#define inf 0x3f3f3f3f
const lli maxn = 22000;
struct edge{
lli to,next,v;
}ed[maxn*10];
lli d[maxn],cur[maxn],pre[maxn],gap[maxn],q[maxn+2000],cnte,head[maxn];
void ae(lli x, lli y, lli v) {
ed[cnte].to = y;
ed[cnte].v = v;
ed[cnte].next = head[x];
head[x] = cnte++;
ed[cnte].to = x;
ed[cnte].v = 0;
ed[cnte].next = head[y];
head[y] = cnte++;
}
void rbfs (lli s,lli t) {
lli fi,se;
memset(gap,0,sizeof(gap));
memset(d,-1,sizeof(d));
d[t] = 0;
gap[0] = 1;
fi = se = 0;
q[se++] = t;
while (fi != se) {
lli u = q[fi++];
for (lli i=head[u];~i;i=ed[i].next) {
lli v = ed[i].to;
if (~d[v]) continue;
d[v] = d[u] + 1;
q[se++] = v;
gap[d[v]]++;
}
}
}
lli isap(lli s,lli t){
memcpy(cur,head,sizeof(head));
rbfs (s,t);
lli flow = 0,u = pre[s] = s,i;
while(d[s] < t+1) {
if(u==t) {
lli f = inf,neck;
for(i=s;i!=t;i=ed[cur[i]].to){
if(f > ed[cur[i]].v){
f = ed[cur[i]].v;
neck = i;
}
}
for(i=s;i!=t;i=ed[cur[i]].to){
ed[cur[i]].v -= f;
ed[cur[i]^1].v += f;
}
flow += f;
u = neck;
}
for(i=cur[u];~i;i=ed[i].next) if(d[ed[i].to]+1 == d[u] && ed[i].v) break;
if(~i) {
cur[u] = i;
pre[ed[i].to] = u;
u = ed[i].to;
}
else{
if(gap[d[u]]==0||0 == (--gap[d[u]]) ) break;
lli mind = t+1;
for(i=head[u];~i;i=ed[i].next){
if(ed[i].v && mind>d[ed[i].to]){
cur[u] = i;
mind = d[ed[i].to];
}
}
d[u] = mind + 1;
gap[d[u]]++;
u = pre[u];
}
}
return flow;
}
struct pp{
int a,b;
}res[2600];
lli fx[11000];
void ini(){
memset(head,-1,sizeof(head));cnte = 0;
}
int main(){
int n,s = 0,t = 10200;
while(~scanf("%d",&n)){
ini();
map<lli,int> ma;int order = 2500;
for(int i = 1;i <= n;i++){
scanf("%d%d",&res[i].a,&res[i].b);
lli t1 = res[i].a+res[i].b, t2 = res[i].a-res[i].b, t3 = (lli)res[i].a*(lli)res[i].b;
if(!ma[t1]){
ma[t1] = ++order;fx[order] = t1;
}
if(!ma[t2]){
ma[t2] = ++order;fx[order] = t2;
}
if(!ma[t3]){
ma[t3] = ++order;fx[order] = t3;
}
}
for(int i = 1;i <= n;i++){
lli t1 = res[i].a+res[i].b, t2 = res[i].a-res[i].b, t3 = (lli)res[i].a*(lli)res[i].b;
ae(s,i,1);
ae(i,ma[t1],1);
if(t2 != t1)
ae(i,ma[t2],1);
if(t3 != t2 && t3 != t1)
ae(i,ma[t3],1);
}
for(int i = 2501;i <= order;i++){
ae(i,t,1);
}
if(isap(s,t) == n){
for(int i = 1;i <= n;i++){
for(int j = head[i];~j;j=ed[j].next){
int to = ed[j].to;
if(ed[j].v == 0){
if(res[i].a+res[i].b == fx[to]){
printf("%d + %d = %I64d\n",res[i].a,res[i].b,fx[to]);
}
else if(res[i].a-res[i].b == fx[to]){
printf("%d - %d = %I64d\n",res[i].a,res[i].b,fx[to]);
}
else if((lli)res[i].a*(lli)res[i].b == fx[to]){
printf("%d * %d = %I64d\n",res[i].a,res[i].b,fx[to]);
}
break;
}
}
}
}
else{
puts("impossible");
}
}
}