2017.10.19离线赛总结
2017-10-20 11:05
295 查看
vigenere ——4106
思路:水题,不解释。game ——4107
思路:乍一看题意,求最大值最小,脑海中直接蹦出二分答案,然而看清楚题意,再看看数据范围,貌似可以贪心,且可以先估计按L或R 排序。再仔细推出,答案应该是 max{∏ij=1Lj(Li∗Ri)} 。
根据式子,可以看出是按照L*R来排序的。
首先,我们只知道∏ni=1Li,那么,若最后一个与倒数第二个交换一下,就会发现ans变了,也经过2小时的对拍…可以说是正确的,应该也是显然的。(比赛贪心哪要这么多的证明)
#include<bits/stdc++.h> #define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;i++) #define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;i--) #define N 1005 #define L 4005 #define P 10000 #define LL long long using namespace std; int n; struct node{ int a,b,id; bool operator<(const node &_)const{ return a*b<_.a*_.b; } }A ; struct p60{ void chkmax(LL &x,LL y){ ed58 if(x<y)x=y;} LL a,b,ans; void solve(){ scanf("%lld%lld",&a,&b); REP(i,1,n)scanf("%d%d",&A[i].a,&A[i].b); sort(A+1,A+1+n); REP(i,1,n){ LL res=a/A[i].b; chkmax(ans,res); a*=A[i].a; } cout<<ans<<endl; } }p60; struct p100{ struct Big{ int num[L],len; Big(){ memset(num,0,sizeof(num)); len=1; } Big operator *(const int &a)const{ Big b; b.len=len; REP(i,0,len-1){ int &B=b.num[i]; B+=num[i]*a; if(B>=P)b.num[i+1]+=B/P,B%=P; } if(b.num[b.len])b.len++; return b; } Big operator /(const int &a)const{ Big b; REP(i,0,len-1)b.num[i]=num[i]; DREP(i,len-1,1)b.num[i-1]+=b.num[i]%a*P,b.num[i]/=a; b.num[0]/=a; b.len=len; while(b.len>1 && !b.num[b.len-1])b.len--; return b; } void Rd(){ char A[L]; scanf("%s",A); int SL=strlen(A); len=0; for(int i=SL-1,res;res=0,i>=0;num[len++]=res,i-=4){ if(i>=3)for(int j=i-3;j<=i;j++)res=(res<<1)+(res<<3)+(A[j]^48); else for(int j=0;j<=i;j++)res=(res<<1)+(res<<3)+(A[j]^48); } } void Pr(){ printf("%d",num[len-1]); DREP(i,len-2,0)printf("%04d",num[i]); } }Ans,Sum,Tmp; void Max(Big &a,Big b){ if(b.len>a.len)a=b; else if(a.len==b.len){ if(a.num[a.len-1]<b.num[b.len-1])a=b; } } void solve(){ Sum.Rd(); LL b;cin>>b; REP(i,1,n)scanf("%d%d",&A[i].a,&A[i].b); sort(A+1,A+1+n); REP(i,1,n){ Tmp=Sum; Tmp=Tmp/A[i].b; Max(Ans,Tmp); Sum=Sum*A[i].a; } Ans.Pr(); } }p100; int main(){ // freopen("game.in","r",stdin); // freopen("game.out","w",stdout); scanf("%d",&n); if(n<=100)p60.solve(); else p100.solve(); // p100.solve(); return 0; }
drive ——4108
思路:预处理倍增,然后模拟,与暴力思路类似。(然而暴力又没敲T_T)#include<bits/stdc++.h> #define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;i++) #define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;i--) #define LL long long #define INF 0x3f3f3f3f #define N 100005 #define T 20 using namespace std; int n,m; int nxtb ,nxta ; struct p70{ int h ; void Init(){ REP(i,1,n-1){ int a=0,b=0,mn=INF; REP(j,i+1,n){ int dx=abs(h[j]-h[i]); if(dx<mn)mn=dx,a=j; else if(dx==mn&&h[j]<h[a])a=j; } mn=INF; REP(j,i+1,n){ if(j==a)continue; int dx=abs(h[j]-h[i]); if(dx<mn)mn=dx,b=j; else if(dx==mn&&h[j]<h[b])b=j; } nxtb[i]=a;nxta[i]=b; } } void solve(){ REP(i,1,n)scanf("%d",&h[i]); int x0;cin>>x0; Init(); int pos; double mn=INF; REP(i,1,n){ int f=1,beg=i,xi=x0; LL l1=0ll,l2=0ll; while(xi){ if(f){ if(!nxta[beg])break; int dx=abs(h[beg]-h[nxta[beg]]); if(dx>xi)break; l1+=dx;xi-=dx; beg=nxta[beg]; f=0; } else { if(!nxtb[beg])break; if(abs(h[beg]-h[nxtb[beg]])>xi)break; l2+=abs(h[beg]-h[nxtb[beg]]); xi-=abs(h[beg]-h[nxtb[beg]]); beg=nxtb[beg]; f=1; } } double tmp; if(!l2){ tmp=INF; if(tmp<mn)mn=tmp,pos=i; else if(tmp==mn&&h[i]>h[pos])pos=i; } else { tmp=double(l1*1.0/l2); if(tmp<mn)mn=tmp,pos=i; else if(tmp==mn&&h[i]>h[pos])pos=i; } } printf("%d\n",pos); cin>>m; REP(i,1,m) { int beg,xi; scanf("%d%d",&beg,&xi); int f=1; LL l1=0ll,l2=0ll; while(xi){ if(f){ if(!nxta[beg])break; int dx=abs(h[beg]-h[nxta[beg]]); if(dx>xi)break; l1+=dx;xi-=dx; beg=nxta[beg]; f=0; } else { if(!nxtb[beg])break; int dx=abs(h[beg]-h[nxtb[beg]]); if(dx>xi)break; l2+=dx;xi-=dx; beg=nxtb[beg]; f=1; } } printf("%lld %lld\n",l1,l2); } } }p70; LL fa [T],fb [T],f [T]; struct node{ int h,id; bool operator<(const node &a)const{ return h<a.h; } }A ; set<node>S; set<node>::iterator it; struct car{ int id,dis; bool operator<(const car &a)const{ if(dis==a.dis)return A[id].h<A[a.id].h; else return dis<a.dis; } }tmp[10]; struct p100{ void Init(int i){ set<node>::iterator it=S.find(A[i]); int cnt=0; if(it!=S.begin()){ --it; tmp[++cnt]=(car){it->id,abs(A[i].h-it->h)}; if(it!=S.begin()){ --it; tmp[++cnt]=(car){it->id,abs(A[i].h-it->h)}; ++it; } ++it; } if((++it)!=S.end()){ tmp[++cnt]=(car){it->id,abs(A[i].h-it->h)}; if((++it)!=S.end())tmp[++cnt]=(car){it->id,abs(A[i].h-it->h)}; } sort(tmp+1,tmp+1+cnt); nxtb[i]=tmp[1].id; if(cnt!=1)nxta[i]=tmp[2].id; } void work(int beg,int x,LL &l1,LL &l2){ DREP(j,T-1,0){ if(f[beg][j] && fa[beg][j]+fb[beg][j]<=x){ l1+=fa[beg][j],l2+=fb[beg][j]; x-=fa[beg][j]+fb[beg][j]; beg=f[beg][j]; } } int x1=nxta[beg]; if(!x1)return; int d=abs(A[beg].h-A[x1].h); if(d<=x)l1+=d; } void solve(){ REP(i,1,n)scanf("%d",&A[i].h),A[i].id=i; S.insert(A ); DREP(i,n-1,1)S.insert(A[i]),Init(i); REP(i,1,n){ int x1=nxta[i],x2=nxtb[nxta[i]]; fa[i][0]=x1?abs(A[i].h-A[x1].h):0; fb[i][0]=x2?abs(A[x1].h-A[x2].h):0; f[i][0]=x2; } REP(j,1,T-1) REP(i,1,n){ f[i][j]=f[f[i][j-1]][j-1]; fa[i][j]=fa[i][j-1]+fa[f[i][j-1]][j-1]; fb[i][j]=fb[i][j-1]+fb[f[i][j-1]][j-1]; } int x0; cin>>x0>>m; LL ansa=1e18,ansb=0ll; int pos=0; REP(i,1,n){ LL l1=0ll,l2=0ll; work(i,x0,l1,l2); if (l2 && (!pos || l1*ansb<l2*ansa)){ ansa=l1;ansb=l2; pos=i; } } printf("%d\n",pos); while(m--){ int beg,xi; scanf("%d%d",&beg,&xi); LL l1=0ll,l2=0ll; work(beg,xi,l1,l2); printf("%lld %lld\n",l1,l2); } } }p100; int main(){ // freopen("drive.in","r",stdin); // freopen("drive.out","w",stdout); cin>>n; if(n<=1000)p70.solve(); else p100.solve(); return 0; }
小结:这次考试暴力又没敲,实则就是自己不会打,而且第2题切分又切错了T_T…
相关文章推荐
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
- Vim常见指令与问题总结(五)---windowns下vim离线安装插件及介绍
- 2017.10.27离线赛总结
- 2017-10-29离线赛总结
- 20171009离线赛总结
- 2017-10-9离线赛总结
- 完整的ubuntu镜像源/本地源/更新源/离线升级包!制作总结!
- 经验分享:迅雷离线下载无线端设计总结
- 2017-11-3离线赛总结
- 2017-11-5离线赛总结(NOIP七连测第三场)
- 2017-11-8离线赛总结
- 17.7.26离线赛比赛总结
- 2017-9-28离线赛总结
- 2017/7/29 离线赛 总结
- 2017.10.29离线赛总结
- 离线缓存与客户端存储总结
- 2017.10.19 第九天总结
- 离线赛20171007总结
- 2017-10-8离线赛总结
- win8离线安装.net 3.5【总结-非原创】