T1——card——其实就是16个if
#include<iostream> #include<cstdio> using namespace std; char c[1010];int n,b,g,r; int main() { freopen("card.in","r",stdin); freopen("card.out","w",stdout); scanf("%d",&n);scanf("%s",c); for(int i=0;i<n;i++) if(c[i]=='B')b++; else if(c[i]=='G')g++; else if(c[i]=='R')r++; if(r&&g&&b)puts("BGR"); else if(r>=2&&g>=2)puts("BGR"); else if(r>=2&&b>=2)puts("BGR"); else if(g>=2&&b>=2)puts("BGR"); else if(r>=2&&g)puts("BG"); else if(r>=2&&b)puts("BG"); else if(g>=2&&r)puts("BR"); else if(g>=2&&b)puts("BR"); else if(b>=2&&r)puts("GR"); else if(b>=2&&g)puts("GR"); else if(b&&g)puts("R"); else if(b&&r)puts("G"); else if(g&&r)puts("B"); else if(b)puts("B"); else if(g)puts("G"); else if(r)puts("R"); return 0; }
T2——win(have bug)——其实是3分法,但是我用二分做,A了,但是发现其实是有bug的。
比如2 3 4 7 7的时候,取中位数为4,正确答案应该是0.66,然而我的变成0.6。
还是数据太弱了额。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } int n,a[100010]; double res=0; long long h[100010]; int main() { freopen("win.in","r",stdin); freopen("win.out","w",stdout); n=read(); for(int i=1;i<=n;i++)a[i]=read(); sort(a+1,a+n+1); for(int i=1;i<=n;i++)h[i]=h[i-1]+a[i]; if(n<=2){puts("0.00");return 0;} for(int i=1;i<=n;i++){ int l=1,r=min(i-1,n-i),ans=0; while(l<=r){ int mid=(l+r)>>1; int tmp=a[i-mid]+a[n-mid+1]; if(a[i]*2<tmp){ans=mid;l=mid+1;} else r=mid-1; } double t; if(!ans)continue; t=h[i]-h[i-ans-1]+h[n]-h[n-ans]; t/=ans*2+1;t-=a[i]; if(res<t)res=t; } printf("%.2lf\n",res); return 0; }
T3——key——看起来很丧,其实,一语点破迷津,——枚举密码,查找是否存在,查找前预处理每一个数的上一个其他数字的位置。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } int n,k[1010],ans=0; char c[1000010]; int las[1000010][10],x[10]; bool check(){ for(int i=1;i<=n;i++){ int now,fr=k[i]-1; for(now=4;now>=1;now--){ if(las[fr][x[now]]!=-1) fr=las[fr][x[now]]; else break; } if(now)return 0; } return 1; } int main() { freopen("key.in","r",stdin); freopen("key.out","w",stdout); n=read(); for(int i=1;i<=n;i++){ scanf("%d",&k[i]);k[i]+=k[i-1]; scanf("%s",c); int tmp[10]; for(int j=0;j<=9;j++)tmp[j]=-1; for(int j=k[i-1];j<k[i];j++){ tmp[c[j-k[i-1]]-'0']=j; for(int l=0;l<=9;l++) las[j][l]=tmp[l]; } } for(x[1]=0;x[1]<=9;x[1]++) for(x[2]=0;x[2]<=9;x[2]++) for(x[3]=0;x[3]<=9;x[3]++) for(x[4]=0;x[4]<=9;x[4]++) if(check())ans++; printf("%d\n",ans); return 0; }
T4——tri——啊,太丧了,(以后补上好了)。
T2——win——仍然是用二分做,但是不存在bug了。
先前是以中位数为关键值,就是当前选择的两个数的平均数与中位数比较,如果大于中位数,就选择它们。
当然这是错误的,因为会将先前更大的平均数拉低。
所以,就考虑与选mid+1个比较。于是就有了以下的二分。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } int n,a[100010]; double res=0; long long h[100010]; double f(int w,int l){ long long t=0; t+=h[w]-h[w-l-1]+h[n]-h[n-l]; return (double)t/(l*2+1)-a[w]; } int main() { freopen("win.in","r",stdin); freopen("win.out","w",stdout); n=read(); for(int i=1;i<=n;i++)a[i]=read(); sort(a+1,a+n+1); for(int i=1;i<=n;i++)h[i]=h[i-1]+a[i]; if(n<=2){puts("0.00");return 0;} for(int i=1;i<=n;i++){ int l=1,r=min(i-1,n-i),ans=0; while(l<=r){ int mid=(l+r)>>1; double w1=f(i,mid),w2=f(i,min(mid+1,r)); if(w1>=w2){ans=mid;r=mid-1;} else l=mid+1; } double t=f(i,ans); //printf("%d %.3lf\n",ans,t); if(res<t)res=t; } printf("%.2lf\n",res); return 0; }
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。