My brute
Time Limit: 2000/1000 MS (Java/others) memory limit: 32768/32768 K (Java/Others)
Total submission (s): 492 accepted submission (s): 180
Problem descriptionseaco is a beautiful girl and likes play a game called "My brute ". before Valentine's Day, starvae and Xingxing ask seaco if she wants to spend the valentine's day with them, but seaco only can spend it with one of them. it's hard to choose from the two excellent
Boys. So there will be a competition between starvae and Xingxing. The competition is like the game "My brute ".
Now starvae have n brutes named From S1 to SN and Xingxing's brutes are named from X1 to XN. A competition consists of N games. at the beginning, starvae's brute Si must versus Xingxing's brute Xi. but it's hard for starvae to win the competition, so starvae
Can change his brutes 'order to win more games. for the starvae's brute Si, if it wins the game, starvae can get VI scores, but if it loses the game, starvae will lose VI scores. before the competition, starvae's score is 0. each brute can only play one game.
After N games, if starvae's score is larger than 0, we say starvae win the competition, otherwise starvae lose it.
It's your time to help starvae change the brutes 'order to make starvae's final score be the largest. if there are multiple orders, you should choose the one whose order changes the least from the original one. the original order is S1, S2, S3... A Sn-1, Sn, while
The final order is up to you.
For starvae's brute Si (maybe this brute is not the original brute Si, it is the ith brute after you ordered them) and Xingxing's brute XI, at first Si has Hi HP and Xi has pi hp, Si's damage is Ai and Xi's is Bi, in other words, if Si attacks, Xi will lose
Ai hp and if Xi attacks, SI will lose Bi HP, Si attacks first, then it's Xi's turn, then si... Until one of them's HP is less than 0 or equal to 0, that, it lose the game, and the other win the game.
Come on, starvae's happiness is in your hand!
Inputfirst line is a number n. (1 <= n <= 90) then follows a line with N numbers mean V1 to VN. <VI <1000) then follows a line with N numbers mean H1 to hn. (1 <= Hi <= 100) then follows a line with N numbers mean P1 to PN. (1 <= pI <= 100) then follows a line with N numbers
Mean A1 to. (1 <= AI <= 50) then follows a line with N numbers mean B1 to bn. (1 <= Bi <= 50) a zero signals the end of input and this test case is not to be processed.
Outputfor each test case, if starvae can win the competition, print the largest score starvae can get, and then follow a real percentage means the similarity between the original order and the final order you had changed, round it to three digits after the decimal
Point. If starvae can't win the competition after changing the order, please just print "oh, I lose my dear seaco !" Maybe the sample can help you get it.
Sample Input
34 5 66 8 1012 14 167 7 67 3 534 5 66 8 1012 14 165 5 55 5 50
Sample output
7 33.333%Oh, I lose my dear seaco!
Authorstarvae
Sourcehdu "Valentines Day" Open Programming
Contest 2010-02-14
Recommendwxl is the second requirement. I don't know how to get it ~~
The optimal matching of a bipartite graph. A graph can be easily created. When processing the similarity. Each weight is increased by 100 times. And then the special mark when I = J. So that their weights are plus + 1. It is easy to pick out the options later. Match by original
Number of matches. 100 * (double) (RES % 100)/n. The second question is displayed.
#include <cstring>#include <cstdio>#include <queue>#include <iostream>#define inf 0x3f3f3f3f#define MAXN 3000#define MAXM 30000using namespace std;struct node{ int u,v,f,c;};node e[MAXM];int first[MAXN],next[MAXM],cc;int inq[MAXN],pre[MAXN],preedge[MAXN],d[MAXN];inline void add_edge(int u,int v,int f,int c){ e[cc].u=u; e[cc].v=v; e[cc].f=f; e[cc].c=c; next[cc]=first[u]; first[u]=cc; cc++; e[cc].v=u; e[cc].u=v; e[cc].f=0; e[cc].c=-c; next[cc]=first[v]; first[v]=cc; cc++;}int SPFA(int s,int t){ memset(inq,0,sizeof(inq)); int i; for(i=0;i<=t;i++) d[i]=-inf; memset(pre,-1,sizeof(pre)); memset(preedge,-1,sizeof(preedge)); d[s]=0; queue<int> q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; int i; for(i=first[u];i!=-1;i=next[i]) { int v=e[i].v; if(e[i].f) { if(d[v]<d[u]+e[i].c) { d[v]=d[u]+e[i].c; pre[v]=u; preedge[v]=i; if(!inq[v]) { inq[v]=1; q.push(v); } } } } } if(d[t]==-inf) return 0; else return 1;}int Min_Cost_Flow(int s,int t){ int ans_flow=0,ans_cost=0,mm,tmp; while(SPFA(s,t)) { mm=inf; int u=t; while(pre[u]!=-1) { tmp=preedge[u]; mm=min(mm,e[tmp].f); u=pre[u]; } u=t; while(pre[u]!=-1) { tmp=preedge[u]; e[tmp].f-=mm; e[tmp^1].f+=mm; u=pre[u]; } ans_flow+=mm; ans_cost+=mm*d[t]; } return ans_cost;}int V[100],H[100],P[100],A[100],B[100];int win(int i,int j){ int x,y; if(P[j]%A[i]==0) x=P[j]/A[i]; else x=P[j]/A[i]+1; if(H[i]%B[j]==0) y=H[i]/B[j]; else y=H[i]/B[j]+1; if(x<=y) return 1; else return 0;}int main(){ int n; while(scanf("%d",&n),n) { memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); cc=0; int i; for(i=1;i<=n;i++) scanf("%d",&V[i]); for(i=1;i<=n;i++) scanf("%d",&H[i]); for(i=1;i<=n;i++) scanf("%d",&P[i]); for(i=1;i<=n;i++) scanf("%d",&A[i]); for(i=1;i<=n;i++) scanf("%d",&B[i]); int s=0,t=2*n+1,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(win(i,j)) { if(i==j) add_edge(i,n+j,1,V[i]*100+1); else add_edge(i,n+j,1,V[i]*100); } else { if(i==j) add_edge(i,n+j,1,-V[i]*100+1); else add_edge(i,n+j,1,-V[i]*100); } } } for(i=1;i<=n;i++) { add_edge(0,i,1,0); add_edge(n+i,t,1,0); } int res=Min_Cost_Flow(s,t); if(res/100<=0) printf("Oh, I lose my dear seaco!\n"); else printf("%d %.3f%%\n",res/100,100*1.0*(res%100)/n); } return 0;}
If you try it, you can make it a two-dimensional one:
#include <cstring>#include <cstdio>#include <queue>#include <iostream>#define inf 0x3f3f3f3f#define MAXN 3000#define MAXM 30000using namespace std;struct node{ int u,v,f,c; int c1;};node e[MAXM];int first[MAXN],next[MAXM],cc,ss;int inq[MAXN],pre[MAXN],preedge[MAXN],d[MAXN],d1[MAXN];inline void add_edge(int u,int v,int f,int c,int c1){ e[cc].u=u; e[cc].v=v; e[cc].f=f; e[cc].c=c; e[cc].c1=c1; next[cc]=first[u]; first[u]=cc; cc++; e[cc].v=u; e[cc].u=v; e[cc].f=0; e[cc].c=-c; e[cc].c1=-c1; next[cc]=first[v]; first[v]=cc; cc++;}int SPFA(int s,int t){ memset(inq,0,sizeof(inq)); int i; for(i=0;i<=t;i++) d1[i]=d[i]=-inf; memset(pre,-1,sizeof(pre)); memset(preedge,-1,sizeof(preedge)); d[s]=0; d1[s]=0; queue<int> q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; int i; for(i=first[u];i!=-1;i=next[i]) { int v=e[i].v; if(e[i].f) { if(d[v]<d[u]+e[i].c||(d[v]==d[u]+e[i].c&&d1[v]<d1[u]+e[i].c1)) { d[v]=d[u]+e[i].c; d1[v]=d1[u]+e[i].c1; pre[v]=u; preedge[v]=i; if(!inq[v]) { inq[v]=1; q.push(v); } } } } } if(d[t]==-inf) return 0; else return 1;}int Min_Cost_Flow(int s,int t){ int ans_flow=0,ans_cost=0,mm,tmp; ss=00; while(SPFA(s,t)) { mm=inf; int u=t; while(pre[u]!=-1) { tmp=preedge[u]; mm=min(mm,e[tmp].f); u=pre[u]; } u=t; while(pre[u]!=-1) { tmp=preedge[u]; e[tmp].f-=mm; e[tmp^1].f+=mm; u=pre[u]; } ans_flow+=mm; ans_cost+=mm*d[t]; ss+=d1[t]; } return ans_cost;}int V[100],H[100],P[100],A[100],B[100];int win(int i,int j){ int x,y; if(P[j]%A[i]==0) x=P[j]/A[i]; else x=P[j]/A[i]+1; if(H[i]%B[j]==0) y=H[i]/B[j]; else y=H[i]/B[j]+1; if(x<=y) return 1; else return 0;}int main(){ int n; while(scanf("%d",&n),n) { memset(first,-1,sizeof(first)); memset(next,-1,sizeof(next)); cc=0; int i; for(i=1;i<=n;i++) scanf("%d",&V[i]); for(i=1;i<=n;i++) scanf("%d",&H[i]); for(i=1;i<=n;i++) scanf("%d",&P[i]); for(i=1;i<=n;i++) scanf("%d",&A[i]); for(i=1;i<=n;i++) scanf("%d",&B[i]); int s=0,t=2*n+1,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(win(i,j)) { if(i==j) add_edge(i,n+j,1,V[i],1); else add_edge(i,n+j,1,V[i],0); } else { if(i==j) add_edge(i,n+j,1,-V[i],1); else add_edge(i,n+j,1,-V[i],0); } } } for(i=1;i<=n;i++) { add_edge(0,i,1,0,0); add_edge(n+i,t,1,0,0); } int res=Min_Cost_Flow(s,t); if(res<=0) printf("Oh, I lose my dear seaco!\n"); else printf("%d %.3f%%\n",res,100*1.0*(ss)/n); } return 0;}