BNU Training 2016.07.25 总结
来源:互联网 发布:sql中minus 编辑:程序博客网 时间:2024/06/06 02:11
比赛链接 https://acm.bnu.edu.cn/v3/contest_show.php?cid=8070#info
AC 5/9
A题:
就不说题意了,递归一下,通通分就好啦。
#include<cstring>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;ll a[2][11];ll len[2];int n,m;ll gcd(ll x,ll y){ if(y==0) return x; return gcd(y,x%y);}template<class T>void read(T&x){ char ch;bool flag; while(!isdigit(ch=getchar())) if(ch=='-') flag=true ; x=ch-'0'; while(isdigit(ch=getchar())) x=x*10+ch-'0'; if(flag) x=-x;}void work(int o,long long &p,long long &q,int x){ if(x==len[o]) { p=a[o][x]; q=1; return; } long long k=a[o][x]; long long xx,yy; work(o,xx,yy,x+1); p=k*xx+yy; q=xx;}void Div(ll &x,ll &y){ ll G=gcd(x,y); x/=G; y/=G;}void Show(ll x,ll y){ if((x<0 &&y>0)||(x>0 && y<0)) { if(x%y==0)printf("%lld",x/y); else { printf("%lld",x/y-1); x=abs(x); y=abs(y); x=y-x%y; } } else printf("%lld",x/y); if(x%y==0) { printf("\n"); return; } printf(" "); Show(y,x%y);}int main(){ int cas=0; while(scanf("%d%d",&n,&m)!=EOF) { ll pa,pb,qa,qb; if(n==0 &&m==0) break; len[0]=n; len[1]=m; for(int i=1;i<=n;i++) scanf("%lld",&a[0][i]); work(0,pa,qa,1); for(int i=1;i<=m;i++) scanf("%lld",&a[1][i]); work(1,pb,qb,1); Div(pa,qa); Div(pb,qb); printf("Case %d:\n",++cas); long long x,y; x=pa*qb+pb*qa; y=qa*qb; Div(x,y); Show(x,y); x=pa*qb-pb*qa; y=qa*qb; Div(x,y); Show(x,y); x=pa*pb; y=qa*qb; Div(x,y); Show(x,y); x=pa*qb; y=qa*pb; Div(x,y); Show(x,y); }}
大原题,折叠字符串。问折叠后的最短长度。比如abbbcdcdcdabbbcdcdcd,最短的折叠方法为2(a3b3(cd)),输出长度11。暴力dp的,还套了个KMP,应该不用套。
#include<cstring>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;char s[505];int last[505];int Len[505];int dp[505][505];template<class T>void read(T&x){ char ch; while(!isdigit(ch=getchar())); x=ch-'0'; while(isdigit(ch=getchar())) x=x*10+ch-'0';}int get_next(int l,int r){ int j=0; int len=r-l+1; for(int i=1;i<=len;i++) last[i]=0; for(int i=2;i<=len;i++) { while(j && s[i+l-1]!=s[j+1+l-1]) j=last[j]; if(s[i+l-1]==s[j+1+l-1]) j++; last[i]=j; } if(len%(len-last[len])==0) return len/(len-last[len]); return 0;}int calc(int l,int r){ if(l>r) return 0; if(dp[l][r]!=-1) return dp[l][r]; int &ans=dp[l][r]; int len=r-l+1; ans=len; int k=get_next(l,r); if(k) { if(k==len) ans=min(ans,Len[k]+1); else ans=min(ans,Len[k]+2+calc(l,l+len/k-1)); } for(int i=l;i<r;i++) ans=min(ans,calc(l,i)+calc(i+1,r)); return ans;}int main(){ for(int i=1;i<=9;i++) Len[i]=1; for(int i=10;i<=99;i++) Len[i]=2; for(int i=100;i<=500;i++) Len[i]=3; int cas=0; int n; while(scanf("%s",s+1)!=EOF) { if(s[1]=='0') return 0; memset(dp,-1,sizeof(dp)); n=strlen(s+1); printf("Case %d: %d\n",++cas,calc(1,n)); }}
C题:
模拟,最关键还是要读懂题=、=
#include<cstring>#include<cstdio>#include<iostream>#include<algorithm>#include<vector>using namespace std;typedef long long ll;struct node{ int x,y; int dx,dy; int valx,valy; node() {} node(int x_,int y_,int dx_,int dy_,int valx_,int valy_) { x=x_; y=y_; dx=dx_; dy=dy_; valx=valx_; valy=valy_; }};vector<node> card,can_use;int b[10];int a[10][10];int score[7][7][7][7][7];int ans;int work(){ sort(b+1,b+6); if(b[1]==b[2] && b[1]==b[3] && b[1]==b[4] && b[1]==b[5]) return 50; for(int i=1; i<=2; i++) if(b[i+1]==b[i] && b[i+2]==b[i] && b[i+3]==b[i]) return 4*b[i]; if(b[2]==b[3] && b[3]==b[4]) return 3*b[2]; if(b[1]==b[2] && b[2]==b[3]) { if(b[4]==b[5]) return 25; else return 3*b[1]; } if(b[3]==b[4] && b[4]==b[5]) { if(b[1]==b[2]) return 25; else return 3*b[3]; } if(b[1]+1==b[2] && b[2]+1==b[3] && b[3]+1==b[4] && b[4]+1==b[5]) return 40; if(b[1]+1==b[2] && b[2]+1==b[3] && b[3]+1==b[4]) return 30; if(b[1]+1==b[2] && b[2]+1==b[3] && b[3]+1==b[5]) return 30; if(b[1]+1==b[2] && b[2]+1==b[4] && b[4]+1==b[5]) return 30; if(b[2]+1==b[3] && b[3]+1==b[4] && b[4]+1==b[5]) return 30; return 0;}void pre(){ for(int i=1; i<=6; i++) for(int j=1; j<=6; j++) for(int k=1; k<=6; k++) for(int l=1; l<=6; l++) for(int o=1; o<=6; o++) { b[1]=i; b[2]=j; b[3]=k; b[4]=l; b[5]=o; score[i][j][k][l][o]=work(); }}int calc(){ int ans=0; int same=0; for(int i=1; i<=5; i++) { if(a[i][1]==a[i][2] && a[i][1]==a[i][3] && a[i][1]==a[i][4] && a[i][1]==a[i][5]) same++; ans+=score[ a[i][1] ][ a[i][2] ][ a[i][3] ][ a[i][4] ][ a[i][5] ]; } for(int i=1; i<=5; i++) { if(a[1][i]==a[2][i] && a[1][i]==a[3][i] && a[1][i]==a[4][i] && a[1][i]==a[5][i]) same++; ans+=score[ a[1][i] ][ a[2][i] ][ a[3][i] ][ a[4][i] ][ a[5][i] ]; } if(a[1][1]==a[2][2] && a[1][1]==a[3][3] && a[1][1]==a[4][4] && a[1][1]==a[5][5]) same++; ans+=score[ a[1][1] ][ a[2][2] ][ a[3][3] ][ a[4][4] ][ a[5][5] ]; if(a[1][5]==a[2][4] && a[1][5]==a[3][3] && a[1][5]==a[4][2] && a[1][5]==a[5][1]) same++; ans+=score[ a[1][5] ][ a[2][4] ][ a[3][3] ][ a[4][2] ][ a[5][1] ]; if(same==0) return ans; return ans+(same-1)*50;}bool used[10][10];int main(){ pre(); int sk; scanf("%d",&sk); for(int cas=1; cas<=sk; cas++) { char opt[3]; int x,y; memset(a,0,sizeof(a)); memset(used,0,sizeof(used)); card.clear(); card.push_back(node(0,0,0,0,0,0)); for(int i=1; i<=5; i++) for(int j=1; j<=5; j++) if(!a[i][j]) { scanf("%s",opt); if(opt[0]=='V') { scanf("%d%d",&x,&y); a[i][j]=x; a[i+1][j]=y; used[x][y]=used[y][x]=true; card.push_back(node(i,j,1,0,x,y)); } else if(opt[0]=='H') { scanf("%d%d",&x,&y); a[i][j]=x; a[i][j+1]=y; used[x][y]=used[y][x]=true; card.push_back(node(i,j,0,1,x,y)); } else { scanf("%d",&x); a[i][j]=x; } } can_use.clear(); can_use.push_back(node(0,0,0,0,0,0)); for(int i=1; i<=6; i++) for(int j=i; j<=6; j++) if(!used[i][j]) can_use.push_back(node(0,0,0,0,i,j)); ans=calc(); for(int i=1; i<=12; i++) { for(int j=1; j<=9; j++) { int x=card[i].x; int y=card[i].y; a[x][y]=can_use[ j ].valx; a[x+card[i].dx][y+card[i].dy]=can_use[ j ].valy; ans=max(ans,calc()); a[x][y]=can_use[ j ].valy; a[x+card[i].dx][y+card[i].dy]=can_use[ j ].valx; ans=max(ans,calc()); a[x][y]=card[i].valx; a[x+card[i].dx][y+card[i].dy]=card[i].valy; } } printf("Case %d: %d\n",cas,ans); }}
不知道为什么可以转化成二分图最大权匹配...有必要再想想
#include<cstring>#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define N 205const int INF=0x3f3f3f3f;int nx,ny,n;int g[N][N];int linker[N],lx[N],ly[N];int slack[N];bool visx[N],visy[N];bool dfs(int x){ visx[x]=true; for(int y=0; y<ny; y++) { if(visy[y]) continue; int tem=lx[x]+ly[y]-g[x][y]; if(tem==0) { visy[y]=true; if(linker[y]==-1 || dfs(linker[y])) { linker[y]=x; return true; } } else if(slack[y]>tem) slack[y]=tem; } return false;}int KM(){ memset(linker,-1,sizeof(linker)); memset(ly,0,sizeof(ly)); for(int i=0; i<nx; i++) { lx[i]=-INF; for(int j=0; j<ny; j++) if(g[i][j]>lx[i]) lx[i]=g[i][j]; } for(int x=0; x<nx; x++) { for(int i=0; i<ny; i++) slack[i]=INF; while(true) { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(dfs(x)) break; int d=INF; for(int i=0; i<ny; i++) if(!visy[i] && d>slack[i]) d=slack[i]; for(int i=0; i<nx; i++) if(visx[i]) lx[i]-=d; for(int i=0; i<ny; i++) if(visy[i]) ly[i]+=d; else slack[i]-=d; } } int res=0; for(int i=0; i<ny; i++) if(linker[i]!=-1) res+=g[linker[i]][i]; return res;}int main(){ int cas=0,sk; scanf("%d",&sk); while(sk--) { scanf("%d",&n); for(int i=0;i<n;i++) g[i][i]=-INF; for(int i=0; i<n; i++) for(int j=i+1; j<n; j++) { int x; scanf("%d",&x); g[j][i]=g[i][j]=-x; } nx=ny=n; printf("Case %d: %d\n",++cas,-KM()); }}/*2410 20 1010 2010415 20 1010 2015*/
0 0
- BNU Training 2016.07.25 总结
- BNU Training 2016.07.12 总结
- BNU Training 2016.07.15 总结
- BNU Training 2016.07.18 总结
- BNU Training 2016.07.22 总结
- BNU Training 2016.07.29 总结
- BNU Training 2016.07.11
- BNU Training 2015.08.17
- 【BNU Summer Training 2014.07.25】 Painting Storages (dp)
- 【BNU Summer Training 2014.07.25】 Final Exam Arrangement (贪心)
- BNU 51640 Training Plan【Dp】
- BNU Training 2016.07.29 Div. 2-B-Levko and Table
- 7.26 team_training (BNU Training 2013.07.26)
- BNU Training 2015 07 27 题解
- BNU新生赛总结
- BNU Training 2017.07.20 【(2+1+0.233)/11】[待补]
- BNU
- USACO Training第一章总结
- module compiled against API version 9 but this version of numpy is 7的解决方法
- tjut 2824
- POJ 1861最小瓶颈树wa
- mybatis下使用log4j打印sql语句和执行结果
- MPTCP 源码分析(七) 拥塞控制
- BNU Training 2016.07.25 总结
- C语言系列(二)有符号数和无符号数详解
- CodeForces 501C Misha and Forest (STL queue)(拓扑排序)
- BestCoder Round #86 HDU 5804(暴力),HDU 5805(前缀和后缀差值最大),HDU 5806(尺取法),HDU 5807(简单DAG 分步式DP )
- Android文本的测量和绘制
- UVA 10305 Ordering Tasks(拓扑排序入门)【刘汝佳算法入门经典例6-15】
- Head First 装饰者模式
- 多线程实现的三个方法
- leetcode No86. Partition List