A.Babs' Box Boutique
一道简单的dfs搜索题,需要两两比较,然后搜到底,得到最大值就行了。比赛时队友写的,我只负责debug。。赛后自己写的。。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 1000000007 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } struct xl { int x,y,z; } a[11]; int n,ans,v[11]; void dfs(int x,int y,int d) { ans=max(d,ans); if(d==n) { return ; } int i; for(i=0; i<n; ++i) { if(v[i]==0) { if(a[i].x>=x&&a[i].y>=y)//对应比较 { v[i]=1; dfs(a[i].x,a[i].y,d+1); v[i]=0; } else if(a[i].x>=x&&a[i].z>=y) { v[i]=1; dfs(a[i].x,a[i].z,d+1); v[i]=0; } else if(a[i].y>=x&&a[i].z>=y) { v[i]=1; dfs(a[i].y,a[i].z,d+1); v[i]=0; } } } } int main() { int i,t[4],cas=0; while(1) { RD(n); if(n==0) { break; } cas++; for(i=0; i<n; ++i) { RD(t[0]); RD(t[1]); RD(t[2]); sort(t,t+3);//注意排序 a[i].x=t[0]; a[i].y=t[1]; a[i].z=t[2]; } ans=0; mem(v,0); dfs(0,0,0); printf("Case %d: ",cas); OT(ans); printf("\n"); } return 0; }
B.Flash Mob
简单的求中位数和曼哈顿距离,直接对xi和yi分别排序,然后取中位数,中位数与其他点求曼哈顿距离。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 1000000007 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } int x[1001],y[1001],n; int f(int a,int b) { int sum=0,i; FOR(1,n,i) { sum+=abs(a-x[i]+b-y[i]); } return sum; } int main() { int i,cas=0; while(1) { RD(n); if(n==0) { break; } cas++; for(i=1;i<=n;++i) { scanf("%d%d",&x[i],&y[i]); } sort(x+1,x+n+1); sort(y+1,y+n+1); printf("Case %d: (%d,%d) %d\n",cas,x[(1+n)/2],y[(n+1)/2],f(x[(1+n)/2],y[(n+1)/2])); } return 0; }
C.Hexagon Perplexagon
一道枚举题,可以dfs搜,也可以用next_permutation得到所有情况然后暴力查找符合条件的值,我用的是next_permutation,险过。。。需要用到二维数组标记。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 1000000007 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } int a[11][11],p[11][11],id[11],high[11],low[11]; int main() { int t,i,j,tt,cas=0; bool f,g; RD(t); while(t--) { cas++; for(i=0; i<7; ++i) { id[i]=i; for(j=0; j<6; ++j) { RD(a[i][j]); } for(j=0; j<6; ++j) { p[i][a[i][j]]=j;//标记数组 } } f=false; do { for(i=1; i<7; ++i) { tt=p[id[0]][1]+i-1; if(tt>=6) { tt-=6; } j=a[id[0]][tt]; tt=p[id[i]][j]+1; if(tt>=6) { tt-=6; } low[i]=a[id[i]][tt]; tt=p[id[i]][j]-1; if(tt<0) { tt+=6; } high[i]=a[id[i]][tt]; } low[7]=low[1]; g=true; for(i=1; i<7; ++i) { if(high[i]!=low[i+1])//左右比较 { g=false; break; } } if(g==true) { f=true; break; } } while(next_permutation(id,id+7)); printf("Case %d: ",cas); if(f==true) { for(i=0; i<6; ++i) { printf("%d ",id[i]); } printf("%d\n",id[6]); } else { printf("No solution\n"); } } return 0; }
D.I've Got Your Back(gammon)
一道映射题,表示不同的检索方式和不同的数代表不同的序列。。。直接暴力就行。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 1000000007 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } int a[6],an[6],num,f[6][16][16]; char c[2]; void init() { int i,j,k; For(0,6,j) { For(0,16,i) { For(0,16,k) { f[j][i][k]=0; } } } } int main() { init(); int i,j,k,l; FOR(1,15,i)//预处理 { FOR(1,15,j) { if(j==i) { f[0][j][i]=1; } else { f[0][j][i]=0; } f[0][0][i]+=f[0][j][i]; } } For(1,6,k) { FOR(1,15,j) { f[k][j][j]=1; f[k][0][j]+=1; for(i=j+1; i<=15; i++) { for(l=k-1; l>=0; l--) { f[k][j][i]+=f[l][0][i-j]; } f[k][0][i]+=f[k][j][i]; } } } int cas=0,num,sum,ans,tmp; while(scanf("%s",c)) { cas++; if(c[0]=='m') { For(0,6,i) { RD(a[i]); } num=15; ans=0; For(0,6,j) { if(a[j]>0) { for(i=4-j; i>=0; i--) { for(k=num-a[j]+1; k<=num; k++) { ans+=f[i][0][k]; } } } num-=a[j]; if(num==0) { ans++; break; } } printf("Case %d: %d\n",cas,ans-1); } else if(c[0]=='u') { For(0,6,j) { an[j]=0; } scanf("%d",&sum); sum++; num=15; ans=0; while(num>0) { ans=0; for(j=0; j<6; j++) { ans+=f[j][0][num]; if(ans>=sum) { break; } } if(ans==sum) { an[j]=num; break; } ans-=f[j][0][num]; sum-=ans; FOR(1,num,i) { tmp=0; For(0,j,k) { tmp+=f[k][0][num-i]; } if(tmp>=sum) { break; } else { sum-=tmp; } } num-=i; an[j]=i; } printf("Case %d: %d %d %d %d %d %d\n",cas,an[5],an[4],an[3],an[2],an[1],an[0]); } else { break; } } return 0; }
F.Road Series
。。。UESTC和UVALive两个source的题目限时不同,我一直交UESTC,TLE到死。。。。
交了UVALive就A了,我不想再说什么了,无力了~~~~~~
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 1000000007 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } set<int>p; set<int>::iterator it; string q[1001],ss; char s[1001]; int k,w,tt; int main() { int t,cas=0,m,i,j,l,sum,a,o; bool f; RD(t); while(t--) { cas++; scanf("%d%d",&k,&w); gets(s); p.clear(); m=0; for(o=0;o<k;++o) { gets(s); tt=0; l=strlen(s); ss=""; for(j=0; j<l; ++j) { if(s[j]>='0'&&s[j]<='9') { ss+=s[j]; } else { q[tt++]=ss; ss=""; } } if(s[l-1]>='0'&&s[l-1]<='9') { q[tt++]=ss; } while(true) { if(p.find(m+1)!=p.end()) { p.erase(m+1); ++m; continue; } for(i=1; i<=w; ++i) { ss=""; a=m+i; if(a==0) { ss="0"; } while(a) { ss=char(a%10+48)+ss; a/=10; } f=false; for(j=0; j<tt; ++j) { if(q[j].find(ss)!=-1) { f=true; break; } } if(f) { p.insert(m+i); } } if (p.find(m+ 1)!=p.end()) { continue; } break; } } sum=m; for(it=p.begin(); it != p.end(); it++) { sum=max(sum,*it); } printf("Case %d: %d %d\n",cas,m,sum); } return 0; }
G.Show Me the Money
汇率兑换,需要用到弗洛伊德算法求最短路的方式得到兑换方式。。。没考虑太多,居然1A,学长说题目说没有重边,但数据里有。。。额,我也没仔细看太清题目,喜闻乐见了~~~
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<set> #include<vector> #include<stack> #include<map> #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(a,b,i) for(i=a;i<=b;++i) #define For(a,b,i) for(i=a;i<b;++i) #define N 1000000007 using namespace std; inline void RD(int &ret) { char c; do { c=getchar(); } while(c<'0'||c>'9'); ret=c-'0'; while((c=getchar())>='0'&&c<='9') { ret=ret*10+(c-'0'); } } inline void OT(int a) { if(a>=10) { OT(a/10); } putchar(a%10+'0'); } map<string,int>q; string ss[11]; long long a[11][11]; int ans,m; string p1,p2,p; void f() { int i,j,k,id,num,l; long long sum=-1,in,aa,bb; char h[22]; FOR(1,ans,i)//floyd { FOR(1,ans,j) { if(i!=j) { FOR(1,ans,k) { if(i!=k&&j!=k)//去重边 { if(a[j][i]==0||a[i][j]==0) { continue; } if(a[j][k]!=0) { continue; } a[j][k]=a[j][i]*a[i][k]; a[k][j]=a[k][i]*a[i][j]; } } } } } id=q[p]; FOR(1,ans,i) { if(i!=id&&a[i][id]!=0) { in=(long long)m*a[i][id]/a[id][i]; if(in*a[id][i]<(long long)m*a[i][id]) { in++; } if(in<=100000) { if(sum==-1||in*a[id][i]*bb<sum*aa*a[i][id]) { sum=in; num=i; aa=a[id][i]; bb=a[i][id]; } } } } l=ss[num].size(); for(i=0; i<l; ++i) { h[i]=ss[num][i]; } h[l]=0; printf("%lld %s\n",sum,h); } int main() { int t,i,cas=0,x,y; char s[11],s1[11],s2[11]; while(1) { RD(t); if(t==0) { break; } cas++; q.clear(); ans=0; mem(a,0); while(t--) { scanf("%d%s%s%d%s",&x,s1,s,&y,s2); p1.assign(s1); p2.assign(s2); if(q[p1]==0)//map去重 { q[p1]=++ans; } ss[q[p1]]=p1; if(q[p2]==0) { q[p2]=++ans; } ss[q[p2]]=p2; a[q[p1]][q[p2]]=x; a[q[p2]][q[p1]]=y; } scanf("%d%s",&m,s); printf("Case %d: ",cas); p.assign(s); f(); } return 0; }
这次做得还行,但前面的水题出得太慢了,导致其它题也没怎么看。。。