{暑假集训}
7.12
错过。。。
7.14
https://vjudge.net/contest/170300#overview
D - Reading Digits
暴力往前推到初始时的串,输出指定位置即可。
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int main() 6 { 7 string s,t; 8 int n,k; 9 scanf("%d%d",&n,&k); 10 cin>>s; 11 for(int i=0;i<n;i++) 12 { 13 int len=s.length(); 14 t=""; 15 for(int j=0;j<len;j++) 16 { 17 int a=s[j]-'0'; 18 int k=0; 19 while(k<a) t+=s[j+1],k++; 20 j++; 21 } 22 s=t; 23 } 24 cout<<s[k]<<endl; 25 }
G - Pokemons
没有想到在线直接处理,一直爆内存。。。怎么那么弱啊
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 double m; 5 int n; 6 7 int main() 8 { 9 scanf("%lf%d",&m,&n); 10 double minp,curp; 11 double ans=0; 12 scanf("%lf",&minp); 13 for(int i=1;i<n;i++) 14 { 15 scanf("%lf",&curp); 16 if(i==1) 17 { 18 ans=(curp-minp)/minp*m; 19 } 20 if(curp<minp) minp=curp; //维护当前最小进价 21 else ans=max(ans,(curp-minp)/minp*m); //当前最大收益 22 } 23 printf("%.2lf\n",ans); 24 }
I - Cubes
dfs+剪枝
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n; 6 int c[410]; 7 int ans[50],a[50],cnt=50;//预估不会超过50层?? 8 void dfs(int d,int n,int k) 9 { 10 if(n==0) 11 { 12 cnt=d; 13 for(int i=1;i<=cnt;i++) a[i]=ans[i]; 14 } 15 if(d+1>=cnt||d+n/c[k]>=cnt) return ; 16 for(int j=k;j>=1;j--) if(c[j]<=n) 17 { 18 ans[d+1]=j; 19 dfs(d+1,n-c[j],j); 20 } 21 } 22 int main() 23 { 24 scanf("%d",&n); 25 for(int i=1;i<=400;i++) c[i]=i*i*i; 26 dfs(0,n,400); 27 printf("%d\n",cnt); 28 for(int i=1;i<cnt;i++) printf("%d ",a[i]); 29 printf("%d\n",a[cnt]); 30 }
7.16
https://vjudge.net/contest/171164#overview
A - Rearranging a Sequence
看到先进后出就用栈做了
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 int n,m; 6 stack <int> s; 7 int vis[200010]; 8 int main() 9 { 10 scanf("%d%d",&n,&m); 11 int cnt=0; 12 for(int i=0;i<m;i++) 13 { 14 int x; 15 scanf("%d",&x); 16 s.push(x); 17 if(!vis[x]) 18 { 19 vis[x]=1; 20 cnt++; 21 } 22 } 23 for(int i=0;i<cnt;i++) 24 { 25 while(vis[s.top()]==2) s.pop(); 26 printf("%d\n",s.top()); 27 vis[s.top()]=2; 28 s.pop(); 29 } 30 for(int i=1;i<=n;i++) 31 if(!vis[i]) printf("%d\n",i); 32 }
B - Quality of Check Digits
没有什么比读错题更坑了,,还是两次读错
题目中没有说只有主对角线有0,但是给的例子都是只有主对角线是0(最后一个忽略),导致判断时出错一直WA在31
代码写的比较丑,凑和吧=_=||
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn=10010; 5 int tb2[10][10]; 6 7 int e[maxn]; 8 9 int main() 10 { 11 for(int i=0;i<10;i++) 12 for(int j=0;j<10;j++) 13 scanf("%d",&tb2[i][j]); 14 for(int i=0;i<10000;i++) 15 { 16 int a=i/1000; 17 int b=i%1000/100; 18 int c=i%100/10; 19 int d=i%10; 20 int x=tb2[0][a]; 21 int y=tb2[x][b]; 22 x=tb2[y][c]; 23 y=tb2[x][d]; 24 e[i]=y; 25 } 26 int cnt=0; 27 for(int i=0;i<10000;i++) 28 { 29 int flag=0; 30 int a=i/1000; 31 int b=i%1000/100; 32 int c=i%100/10; 33 int d= i%10; 34 for(int j=0;j<10&&!flag;j++) if(j!=e[i]) 35 { 36 if(tb2[e[i]][j]==0) 37 { 38 cnt++; 39 flag=1; 40 break; 41 } 42 } 43 for(int j=0;j<10&&!flag;j++) if(j!=a) 44 { 45 int x=j*1000+b*100+c*10+d; 46 if(tb2[e[x]][e[i]]==0) 47 { 48 cnt++; 49 flag=1; 50 break; 51 } 52 } 53 for(int j=0;j<10&&!flag;j++) if(j!=b) 54 { 55 int x=j*100+a*1000+c*10+d; 56 if(tb2[e[x]][e[i]]==0) 57 { 58 cnt++; 59 flag=1; 60 break; 61 } 62 } 63 for(int j=0;j<10&&!flag;j++) if(j!=c) 64 { 65 int x=j*10+a*1000+b*100+d; 66 if(tb2[e[x]][e[i]]==0) 67 { 68 cnt++; 69 flag=1; 70 break; 71 } 72 } 73 for(int j=0;j<10&&!flag;j++) if(j!=d) 74 { 75 int x=j+a*1000+b*100+c*10; 76 if(tb2[e[x]][e[i]]==0) 77 { 78 cnt++; 79 flag=1; 80 break; 81 } 82 } 83 if(flag) continue; 84 85 int x=b*1000+a*100+c*10+d; 86 if(a!=b&&tb2[e[x]][e[i]]==0) 87 { 88 cnt++; 89 flag=1; 90 continue; 91 } 92 93 x=a*1000+c*100+b*10+d; 94 if(c!=b&&tb2[e[x]][e[i]]==0) 95 { 96 cnt++; 97 flag=1; 98 continue; 99 } 100 x=a*1000+b*100+c+d*10; 101 if(c!=d&&tb2[e[x]][e[i]]==0) 102 { 103 cnt++; 104 flag=1; 105 continue; 106 } 107 x=a*1000+b*100+c*10+e[i]; 108 if(d!=e[i]&&tb2[e[x]][d]==0) 109 { 110 cnt++; 111 flag=1; 112 continue; 113 } 114 } 115 cout<<cnt<<endl; 116 }
C - Distribution Center
并没有做出来。。。差一点
要记录一下每次机械臂操作后两条生产线的物品总数,上交和下交分开记录,下次交汇时更新用到。
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int maxn=200010; 6 int last[maxn][2]; //0为上交,1为下交 7 int ans[maxn]; 8 9 struct node 10 { 11 int x,y; 12 bool operator <(const node & a)const 13 { 14 return x<a.x; 15 } 16 }arm[maxn]; 17 int n,m; 18 19 int main() 20 { 21 scanf("%d%d",&n,&m); 22 for(int i=0;i<m;i++) 23 scanf("%d%d",&arm[i].x,&arm[i].y); 24 sort(arm,arm+m); 25 for(int i=0;i<=n;i++) ans[i]=1; 26 for(int i=0;i<m;i++) 27 { 28 int a=arm[i].y; 29 int b=a+1; 30 int dx=ans[a]-last[a][1];// 31 int dy=ans[b]-last[b][0];// 32 ans[a]+=dy; 33 ans[b]+=dx; 34 last[a][1]=ans[a]; 35 last[b][0]=ans[b]; 36 } 37 for(int i=1;i<=n;i++) 38 printf("%d%c",ans[i],i==n?'\n':' '); 39 }
7.18
https://vjudge.net/contest/171646#overview
C - Sums
等号右边用求和公式,枚举个数n求得a1
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 using namespace std; 4 int main() 5 { 6 int t; 7 scanf("%d",&t); 8 while(t--) 9 { 10 int n; 11 int ok=0; 12 scanf("%d",&n); 13 for(int i=2;i<=100000&&(n-(i-1)*i/2)>0;i++) 14 { 15 long long temp=(n-(i-1)*i/2); 16 if(temp%i) continue; 17 ok=1; 18 int a1=temp/i; 19 printf("%d = %d",n,a1); 20 for(int j=1;j<i;j++) 21 { 22 printf(" + %d",++a1); 23 } 24 puts(""); 25 break; 26 27 } 28 if(!ok) puts("IMPOSSIBLE"); 29 } 30 }
D - Wheels
写的有点拉杂,,就这样吧。。。
1 #include <cstdio> 2 #include <bits/stdc++.h> 3 #define LL long long 4 using namespace std; 5 const int maxn=1010; 6 int n; 7 struct node 8 { 9 int x,y,r; 10 int id; 11 }clo[maxn]; 12 int vis[maxn]; 13 queue<node> q[2]; 14 int gcd(int a,int b) 15 { 16 return b==0?a:gcd(b,a%b); 17 } 18 19 double dis(node a,node b) 20 { 21 int dx=a.x-b.x; 22 int dy=a.y-b.y; 23 return sqrt(dx*dx+dy*dy); 24 } 25 void bfs() 26 { 27 q[0].push(clo[0]); 28 clo[0].id=0; 29 vis[0]=1; 30 int mask=0; 31 while(!q[mask].empty()) 32 { 33 node temp=q[mask].front(); 34 q[mask].pop(); 35 for(int i=0;i<n;i++) if(!vis[i]) 36 { 37 double d1=dis(temp,clo[i]); 38 if(d1==temp.r+clo[i].r) 39 { 40 vis[i]=1; 41 clo[i].id=mask^1; 42 q[mask^1].push(clo[i]); 43 } 44 } 45 if(q[mask].empty()) mask^=1; 46 } 47 return ; 48 } 49 int main() 50 { 51 int t; 52 scanf("%d",&t); 53 54 while(t--) 55 { 56 while(!q[0].empty()) q[0].pop(); 57 while(!q[1].empty()) q[1].pop(); 58 memset(vis,0,sizeof(vis)); 59 scanf("%d",&n); 60 for(int i=0;i<n;i++) 61 { 62 scanf("%d%d%d",&clo[i].x,&clo[i].y,&clo[i].r); 63 clo[i].id=2; 64 } 65 int r=clo[0].r; 66 bfs(); 67 for(int i=0;i<n;i++) 68 { 69 if(clo[i].id==0) 70 { 71 int g=gcd(r,clo[i].r); 72 if(r%clo[i].r) printf("%d/%d clockwise\n",r/g,clo[i].r/g); 73 else printf("%d clockwise\n",r/clo[i].r); 74 } 75 else if(clo[i].id==2) 76 { 77 printf("not moving\n"); 78 } 79 else if(clo[i].id==1) 80 { 81 int g=gcd(r,clo[i].r); 82 if(r%clo[i].r) printf("%d/%d counterclockwise\n",r/g,clo[i].r/g); 83 else printf("%d counterclockwise\n",r/clo[i].r); 84 } 85 } 86 } 87 }
H - Good morning!
蒟蒻写表过的=_=||......................................................
1 #include <bits/stdc++.h> 2 #include <cstdio> 3 using namespace std; 4 int ans[10][10]={ 5 0,0,0,0,0,0,10,10,10,10, 6 10,11,12,13,14,15,16,17,18,19, 7 20,20,22,23,25,25,26,28,28,29, 8 29,29,33,33,33,36,36,36,39,39, 9 40,40,44,44,44,45,46,47,48,49, 10 50,50,50,55,55,55,56,56,58,59, 11 59,59,59,66,66,66,66,66,69,69, 12 70,70,70,70,77,77,77,77,78,79, 13 80,80,80,80,88,88,88,88,88,89, 14 89,89,89,89,89,99,99,99,99,99, 15 }; 16 17 int main() 18 { 19 20 int t; 21 scanf("%d",&t); 22 while(t--) 23 { 24 char s[5]; 25 cin>>s; 26 int len=strlen(s); 27 if(len==1) 28 { 29 cout<<s<<endl; 30 continue; 31 } 32 int a=s[len-1]-'0'; 33 int b=s[len-2]-'0'; 34 s[len-2]='\0'; 35 cout<<s; 36 printf("%02d\n",ans[b][a]); 37 38 } 39 40 }
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int x[]={4,1,1,1,2,2,2,3,3,3}; 5 int y[]={2,1,2,3,1,2,3,1,2,3}; 6 int A[300]; 7 int cnt=0; 8 void dfs(int p) 9 { 10 if(p>200) return ; 11 A[cnt++]=p; 12 for(int i=0;i<10;i++) 13 { 14 int t=p%10; 15 if(x[i]>=x[t]&&y[i]>=y[t]) 16 { 17 dfs(p*10+i); 18 } 19 } 20 } 21 22 int main() 23 { 24 int t; 25 scanf("%d",&t); 26 for(int i=1;i<10;i++) dfs(i); 27 A[cnt++]=0; 28 sort(A,A+cnt); 29 while(t--) 30 { 31 int n; 32 scanf("%d",&n); 33 int ans=0,minn=n; 34 for(int i=0;i<cnt;i++) 35 { 36 if(abs(A[i]-n)<minn) 37 { 38 ans=A[i]; 39 minn=abs(A[i]-n); 40 } 41 } 42 printf("%d\n",ans); 43 } 44 }
I - Bricks
场上没写出来,当时判断思路比较混乱
这是参考了大佬的
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=100010; 4 5 int x[maxn],c[maxn]; 6 int main() 7 { 8 int t; 9 scanf("%d",&t); 10 while(t--) 11 { 12 int n; 13 char cc; 14 int b=0,w=0; 15 int ans=0; 16 scanf("%d",&n); 17 for(int i=0;i<n;i++) 18 { 19 scanf("%d %c",&x[i],&cc); 20 if(cc=='W') c[i]=0,w+=x[i]; 21 else c[i]=1,b+=x[i]; 22 } 23 if(w==0||b==0) 24 { 25 printf("%d\n",w+b); 26 continue; 27 } 28 29 int g=__gcd(w,b); 30 w/=g;b/=g; 31 int tw=0,tb=0; 32 33 for(int i=0;i<n;i++) 34 { 35 if(c[i]) //黑色 36 { 37 tb+=x[i]; 38 if(tw&&tw%w==0) 39 { 40 int needb=tw/w*b; 41 if(tb-x[i]>=needb) continue; 42 if(tb>=needb) 43 { 44 tb-=needb; 45 tw=0; 46 ans++; 47 } 48 } 49 } 50 else //白色 51 { 52 tw+=x[i]; 53 if(tb&&tb%b==0) 54 { 55 int needw=tb/b*w; 56 if(tw-x[i]>=needw) continue; 57 if(tw>=needw) 58 { 59 tw-=needw; 60 tb=0; 61 ans++; 62 } 63 } 64 } 65 } 66 printf("%d\n",ans); 67 } 68 }
L - Outer space invaders
区间dp。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define N 605 4 const int INF = 0x3f3f3f3f; 5 struct Node { 6 int l, r, w; 7 } p[N]; 8 int dp[N][N], x[N]; 9 int main() { 10 int t; scanf("%d", &t); 11 while(t--) { 12 int n; scanf("%d", &n); 13 int m = 0; 14 for(int i = 1; i <= n; i++) { 15 int l, r, w; scanf("%d%d%d", &l, &r, &w); 16 p[i] = (Node) { l, r, w }; 17 x[++m] = l; x[++m] = r; 18 } 19 20 sort(x + 1, x + 1 + m); 21 m = unique(x + 1, x + 1 + m) - x - 1; //剩余m个元素,下标从1到m 22 23 for(int i = 1; i <= n; i++) { 24 p[i].l = lower_bound(x + 1, x + 1 + m, p[i].l) - x; 25 p[i].r = lower_bound(x + 1, x + 1 + m, p[i].r) - x; 26 } 27 // memset(dp, INF, sizeof(dp)); 28 for(int len = 1; len <= m; len++) { // dp[st][ed] 消掉st到ed这段区间的人的花费 29 for(int st = 1; st <= m - len + 1; st++) { 30 int ed = st + len - 1, id = 0; 31 for(int i = 1; i <= n; i++) // 找出花费最大的人,这个人只能在属于自己的这段区间解决掉 32 if(st <= p[i].l && p[i].r <= ed) 33 if(id == 0 || p[i].w > p[id].w) id = i; 34 if(id == 0) { dp[st][ed] = 0; continue; } 35 dp[st][ed] = INF; 36 for(int gap = p[id].l; gap <= p[id].r; gap++) // 枚举在哪一点去炸掉这个人最优,因为这个人不能被dp[st][gap-1]到dp[gap+1][ed]的点消除 37 dp[st][ed] = min(dp[st][gap-1] + dp[gap+1][ed] + p[id].w, dp[st][ed]); 38 } 39 } 40 //for(int i = 1; i <= m; i++) 41 // for(int j = i; j <= m; j++) 42 // printf("dp[%d][%d] : %d\n", i, j, dp[i][j]); 43 printf("%d\n", dp[1][m]); 44 } 45 return 0; 46 }
7.20
https://vjudge.net/contest/172313
KM算法相关
A - 奔小康赚大钱
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=310; 5 int n; 6 7 int c[maxn][maxn]; 8 int vg[maxn],vb[maxn]; 9 int eb[maxn],eg[maxn]; 10 int mc[maxn]; 11 int d; 12 13 int dfs(int id) 14 { 15 vg[id]=1; 16 for(int i=0;i<n;i++) 17 { 18 if(vb[i]) continue; //只能访问一次 19 int gap=eg[id]+eb[i]-c[id][i]; 20 if(gap==0) //有边 21 { 22 vb[i]=1; 23 if(mc[i]==-1||dfs(mc[i])) 24 { 25 mc[i]=id; 26 return 1; 27 } 28 } 29 else 30 { 31 d=min(d,gap); //该男最少还需要的期望值 32 } 33 } 34 return 0; 35 } 36 37 void KM() 38 { 39 memset(mc,-1,sizeof(mc)); 40 memset(eg,0,sizeof(eg)); 41 memset(eb,0,sizeof(eb)); 42 for(int i=0;i<n;i++) 43 for(int j=0;j<n;j++) 44 eg[i]=max(c[i][j],eg[i]); 45 46 for(int i=0;i<n;i++) 47 { 48 while(1) 49 { 50 memset(vg,0,sizeof(vg)); 51 memset(vb,0,sizeof(vb)); 52 d=inf; 53 if(dfs(i)) break; 54 for(int i=0;i<n;i++) 55 { 56 if(vg[i]) eg[i]-=d; 57 if(vb[i]) eb[i]+=d; 58 } 59 } 60 } 61 } 62 63 int main() 64 { 65 while(scanf("%d",&n)!=EOF) 66 { 67 memset(c,0,sizeof(c)); 68 for(int i=0;i<n;i++) 69 for(int j=0;j<n;j++) 70 scanf("%d",&c[i][j]); 71 KM(); 72 int ans=0; 73 for(int i=0;i<n;i++) 74 ans+=c[mc[i]][i]; 75 printf("%d\n",ans); 76 } 77 78 }
B - Going Home
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=110; 5 6 int eg[maxn],eb[maxn],vg[maxn],vb[maxn]; 7 int mc[maxn],d; 8 int mx[maxn],my[maxn],hx[maxn],hy[maxn]; 9 int c[maxn][maxn]; 10 char g[maxn][maxn]; 11 int n,m; 12 int ct; 13 int dfs(int id) 14 { 15 vg[id]=1; 16 for(int i=0;i<ct;i++) 17 { 18 if(vb[i]==1) continue; 19 int gap=eg[id]+eb[i]-c[id][i]; 20 if(gap==0) 21 { 22 vb[i]=1; 23 if(mc[i]==-1||dfs(mc[i])) 24 { 25 mc[i]=id; 26 return 1; 27 } 28 } 29 else 30 { 31 d=min(d,gap); 32 } 33 } 34 return 0; 35 } 36 void KM() 37 { 38 memset(mc,-1,sizeof(mc)); 39 memset(eg,-inf,sizeof(eg)); 40 memset(eb,0,sizeof(eb)); 41 42 for(int i=0;i<ct;i++) 43 for(int j=0;j<ct;j++) 44 eg[i]=max(eg[i],c[i][j]); 45 for(int i=0;i<ct;i++) 46 { 47 while(1) 48 { 49 memset(vb,0,sizeof(vb)); 50 memset(vg,0,sizeof(vg)); 51 d=inf; 52 if(dfs(i)) break; 53 for(int i=0;i<ct;i++) 54 { 55 if(vg[i]) eg[i]-=d; 56 if(vb[i]) eb[i]+=d; 57 } 58 } 59 } 60 } 61 int main() 62 { 63 while(scanf("%d%d",&n,&m)&&(n||m)) 64 { 65 memset(c,-inf,sizeof(0)); 66 int cth=0,ctm=0; 67 for(int i=0;i<n;i++) 68 { 69 scanf("%s",g[i]); 70 for(int j=0;j<m;j++) 71 { 72 if(g[i][j]=='H') {hx[cth]=i;hy[cth++]=j;} 73 if(g[i][j]=='m') {mx[ctm]=i;my[ctm++]=j;} 74 } 75 } 76 ct=cth; 77 for(int i=0;i<ct;i++) 78 for(int j=0;j<ct;j++) 79 c[i][j]=-abs(mx[i]-hx[j])-abs(my[i]-hy[j]); //m到H的距离 80 KM(); 81 int ans=0; 82 for(int i=0;i<ct;i++) 83 ans+=c[mc[i]][i]; 84 printf("%d\n",-ans); 85 } 86 }
C - Interesting Housing Problem
题目又说不会分到不喜欢的房间,,竟然没看到。。。读题读错了是硬伤啊=_=||
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=550; 5 6 int c[maxn][maxn]; 7 int vb[maxn],vg[maxn],eb[maxn],eg[maxn]; 8 int mc[maxn]; 9 int d; 10 int n,m,r; 11 12 int dfs(int id) 13 { 14 vg[id]=1; 15 for(int i=0;i<m;i++) 16 { 17 int gap=eg[id]+eb[i]-c[id][i]; 18 if(vb[i]) continue; 19 if(gap==0) 20 { 21 vb[i]=1; 22 if(mc[i]==-1||dfs(mc[i])) 23 { 24 mc[i]=id; 25 return 1; 26 } 27 } 28 else d=min(d,gap); 29 } 30 return 0; 31 } 32 33 int KM() 34 { 35 memset(mc,-1,sizeof(mc)); 36 memset(eb,0,sizeof(eb)); 37 memset(eg,-inf,sizeof(eg)); 38 for(int i=0;i<n;i++) 39 for(int j=0;j<m;j++) 40 eg[i]=max(eg[i],c[i][j]); 41 42 for(int i=0;i<n;i++) 43 { 44 while(1) 45 { 46 memset(vb,0,sizeof(vb)); 47 memset(vg,0,sizeof(vg)); 48 d=inf; 49 if(dfs(i)) break; 50 if(d==inf) return -1; 51 for(int i=0;i<n;i++) if(vg[i]) eg[i]-=d; 52 for(int j=0;j<m;j++) if(vb[j]) eb[j]+=d; 53 } 54 } 55 int ans=0; 56 for(int i=0;i<m;i++) 57 { 58 if(mc[i]!=-1) 59 { 60 if(c[mc[i]][i]!=-inf) ans+=c[mc[i]][i]; 61 else return -1; 62 } 63 } 64 return ans; 65 } 66 67 int main() 68 { 69 int u,v,w; 70 int kase=0; 71 while(scanf("%d%d%d",&n,&m,&r)!=EOF) 72 { 73 for(int i=0;i<n;i++) 74 for(int j=0;j<m;j++) 75 c[i][j]=-inf; 76 for(int i=0;i<r;i++) 77 { 78 scanf("%d%d%d",&u,&v,&w); 79 if(w>=0) c[u][v]=w; 80 } 81 printf("Case %d: %d\n",++kase,KM()); 82 } 83 }
D - Special Fish
KM模板
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=110; 5 int c[maxn][maxn]; 6 int vb[maxn],vg[maxn],eb[maxn],eg[maxn]; 7 int mc[maxn]; 8 int g[maxn]; 9 int d; 10 int n; 11 int dfs(int x) 12 { 13 vg[x]=1; 14 for(int i=0;i<n;i++) 15 { 16 if(vb[i]) continue; 17 int gap=eg[x]+eb[i]-c[x][i]; 18 if(gap==0) 19 { 20 vb[i]=1; 21 if(mc[i]==-1||dfs(mc[i])) 22 { 23 mc[i]=x; 24 return 1; 25 } 26 } 27 else d=min(d,gap); 28 } 29 return 0; 30 } 31 int KM() 32 { 33 memset(mc,-1,sizeof(mc)); 34 memset(eb,0,sizeof(eb)); 35 for(int i=0;i<n;i++) 36 { 37 eg[i]=c[i][0]; 38 for(int j=1;j<n;j++) 39 eg[i]=max(c[i][j],eg[i]); 40 } 41 42 for(int i=0;i<n;i++) 43 { 44 while(1) 45 { 46 memset(vb,0,sizeof(vb)); 47 memset(vg,0,sizeof(vg)); 48 d=inf; 49 if(dfs(i)) break; 50 for(int j=0;j<n;j++) { 51 if(vg[j]) eg[j]-=d; 52 if(vb[j]) eb[j]+=d; 53 } 54 } 55 } 56 int ans=0; 57 for(int i=0;i<n;i++) 58 ans+=c[mc[i]][i]; 59 return ans; 60 } 61 62 int main() 63 { 64 char cc[110]; 65 while(scanf("%d",&n)&&n) 66 { 67 memset(c,0,sizeof(c)); 68 for(int i=0;i<n;i++)scanf("%d",&g[i]); 69 for(int i=0;i<n;i++) 70 { 71 scanf("%s",cc); 72 for(int j=0;j<n;j++) 73 { 74 if(cc[j]=='1') c[i][j]=g[i]^g[j]; 75 } 76 } 77 printf("%d\n",KM()); 78 } 79 80 }
F - One fihgt one
神坑。。。string超时,char就过了。。。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=210; 5 int c[maxn][maxn]; 6 int vb[maxn],vg[maxn],eb[maxn],eg[maxn]; 7 int mc[maxn]; 8 int d; 9 map<string,int> mp; 10 int n,m,k; 11 12 int dfs(int id) 13 { 14 vg[id]=1; 15 for(int i=0;i<m;i++) 16 { 17 int gap=eg[id]+eb[i]-c[id][i]; 18 if(vb[i]) continue; 19 if(gap==0) 20 { 21 vb[i]=1; 22 if(mc[i]==-1||dfs(mc[i])) 23 { 24 mc[i]=id; 25 return 1; 26 } 27 } 28 else d=min(d,gap); 29 } 30 return 0; 31 32 } 33 void KM() 34 { 35 memset(mc,-1,sizeof(mc)); 36 memset(eg,-inf,sizeof(eg)); 37 memset(eb,0,sizeof(eb)); 38 39 for(int i=0;i<n;i++) 40 for(int j=0;j<m;j++) 41 eg[i]=max(eg[i],c[i][j]); 42 43 for(int i=0;i<n;i++) 44 { 45 while(1) 46 { 47 memset(vb,0,sizeof(vb)); 48 memset(vg,0,sizeof(vg)); 49 d=inf; 50 if(dfs(i)) break; 51 for(int i=0;i<n;i++) if(vg[i]) eg[i]-=d; 52 for(int j=0;j<m;j++) if(vb[j]) eb[j]+=d; 53 } 54 } 55 } 56 57 int main() 58 { 59 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 60 { 61 char s1[55],s2[55]; 62 mp.clear(); 63 int h; 64 int id1=0,id2=0; 65 memset(c,-inf,sizeof(c)); 66 for(int i=0;i<k;i++) 67 { 68 scanf("%s%s%d",s1,s2,&h); 69 if(!mp.count(s1)) mp[s1]=id1++; 70 if(!mp.count(s2)) mp[s2]=id2++; 71 int u=mp[s1],v=mp[s2]; 72 c[u][v]=-h; 73 } 74 KM(); 75 int ans=0; 76 for(int i=0;i<m;i++) if(mc[i]!=-1) 77 { 78 ans+=c[mc[i]][i]; 79 } 80 printf("%d\n",-ans); 81 } 82 83 }
发现这么整理有点乱,后面分开了。。。