2017/9/2 离线赛
来源:互联网 发布:sql库位库存分配 编辑:程序博客网 时间:2024/05/24 04:37
T1 UOJ#12 猜数
这题简直是送分题,代码又短又好想,我这样说怕不是要被打。
这题应该算是小学奥数题,由于
我们假设两个数分别是
知道了这些,题目就很简单了,因为
int T;ll a,b;int main(){ Rd(T); while(T--){ Rd(a);Rd(b); ll tmp=sqrt(b/a); Pt(a*tmp+b/tmp),putchar(' '),Pt(a+b),putchar('\n'); } return 0;}
T2 任务
dp是显然的,考试的时候敲了70分和100分的两档,但是100分的敲炸了,我当时存了两个机器的时间差,因为知道不能超过3000,但是又想到会有负值,就存了6000,然后就变得很麻烦了,实际只要再存一下哪个大就行了。下面我就把两档都说一下吧。
70分:状态很简单,就是当前两个机器运行到什么时候。一个存在
100分: 思路很相似,都是存下两个机器的运行时间,但是存的方法不一样,因为我们知道,不可能两个相邻两个任务的时间差超过3000的,所以只要在状态里存一下差值即可。
int n;int A[N],B[N];struct P1{ int dp[2][2][60005]; void check(int &a,int b){ if(a==-1||a>b)a=b; } void solve(){ bool cur=0; memset(dp[cur],-1,sizeof(dp[cur])); dp[cur][0][A[1]]=0; dp[cur][1][0]=B[1]; for(int i=2;i<=n;i++){ cur=!cur; memset(dp[cur],-1,sizeof(dp[cur])); for(int j=0;j<2;j++) for(int k=0;k<=60000;k++) if(~dp[!cur][j][k]){ int tmp=dp[!cur][j][k]; if(j){ check(dp[cur][0][max(k,(tmp-B[i-1]))+A[i]],tmp); check(dp[cur][1][k],tmp+B[i]); }else{ check(dp[cur][0][k+A[i]],tmp); check(dp[cur][1][k],max(tmp,k-A[i-1])+B[i]); } } } int ans=-1; for(int i=0;i<2;i++) for(int j=0;j<=60000;j++) if(~dp[cur][i][j]) check(ans,max(j,dp[cur][i][j])); Pt(ans); putchar('\n'); }}P1;struct P2{ int dp[2][2][M]; void check(int &a,int b){ if(a==-1||a>b)a=b; } void solve(){ bool cur=0; memset(dp[cur],-1,sizeof(dp[cur])); dp[cur][0][A[1]]=A[1]; dp[cur][1][B[1]]=B[1]; for(int i=2;i<=n;i++){ cur=!cur; memset(dp[cur],-1,sizeof(dp[cur])); for(int j=3000;j>=0;j--){ if(~dp[!cur][0][j]){ check(dp[cur][0][A[i]],dp[!cur][0][j]+A[i]); if(B[i]>=j)check(dp[cur][1][B[i]-j],dp[!cur][0][j]+B[i]-j); if(B[i]<=j)check(dp[cur][0][j-B[i]],dp[!cur][0][j]); } if(~dp[!cur][1][j]){ check(dp[cur][1][B[i]],dp[!cur][1][j]+B[i]); if(A[i]>=j)check(dp[cur][0][A[i]-j],dp[!cur][1][j]+A[i]-j); if(A[i]<=j)check(dp[cur][1][j-A[i]],dp[!cur][1][j]); } } } int ans=-1; for(int i=0;i<2;i++) for(int j=0;j<=3000;j++) if(~dp[cur][i][j]) check(ans,dp[cur][i][j]); Pt(ans); putchar('\n'); }}P2;bool chk1(){ if(n>200)return false; for(int i=1;i<=n;i++) if(A[i]>=300||B[i]>=300)return false; return true;}int main(){ Rd(n); for(int i=1;i<=n;i++){ Rd(A[i]);Rd(B[i]); } if(chk1())P1.solve(); else P2.solve(); return 0;}
T3 图操作
这题考试的时候就敲了50分,然后忘开
30分:由于加边是递增的,因此求最小生成树的时候就免了排序,少了一个
50分:只有
70分:没有
100分:其实和70分方法一样,就多了个
struct opr{ int f,a,b;}Q[M];int n,m;struct P1{ struct edge{ int a,b,c; }; struct node{ edge e[1005]; int sz,res; node(){sz=0;} }s[1005]; int fa[1005],sz[1005]; int getfa(int v){ if(fa[v]==v)return v; return fa[v]=getfa(fa[v]); } bool same(int x,int y){ return getfa(x)==getfa(y); } void merge(int x,int y){ int px=getfa(x),py=getfa(y); if(px==py)return; fa[py]=px; sz[px]+=sz[py]; } int calc(int x){ bool f=0; int res=0; for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1; for(int i=1;i<=s[x].sz;i++){ int a=s[x].e[i].a,b=s[x].e[i].b,c=s[x].e[i].c; if(!same(a,b)){ res+=c; merge(a,b); if(sz[fa[a]]==n)f=1; } } if(f)return res; else return 0; } void solve(){ for(int i=1;i<=m;i++) if(Q[i].f==1){ s[i]=s[i-1]; s[i].e[++s[i].sz]=(edge){Q[i].a,Q[i].b,i}; s[i].res=calc(i); Pt(s[i].res); putchar('\n'); }else if(Q[i].f==2){ s[i]=s[i-1]; s[i].sz-=Q[i].a; s[i].res=calc(i); Pt(s[i].res); putchar('\n'); }else{ s[i]=s[i-2]; Pt(s[i].res); putchar('\n'); } }}P1;struct P2{ int fa[N],sz[N]; int getfa(int v){ if(fa[v]==v)return v; return fa[v]=getfa(fa[v]); } bool same(int x,int y){ return getfa(x)==getfa(y); } void merge(int x,int y){ int px=getfa(x),py=getfa(y); if(px==py)return; fa[py]=px; sz[px]+=sz[py]; } void solve(){ bool f=0; ll res=0; for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1; for(int i=1;i<=m;i++){ if(f){ Pt(res),putchar('\n'); continue; } int a=Q[i].a,b=Q[i].b; if(!same(a,b)){ res+=i; merge(a,b); if(sz[fa[a]]==n){ f=1; Pt(res),putchar('\n'); continue; } } Pt(0),putchar('\n'); } }}P2;struct P3{ struct edge{ int v,nxt,pre; }e[M<<1]; struct node{ int a,b,c; }stk[M]; int top; int sz[N],id[N]; int head[N],edgecnt; void add_edge(int a,int b,int c){//把b并到a上,b的原来集合为c e[++edgecnt]=(edge){b,head[a],c};head[a]=edgecnt;sz[a]++;id[b]=a; } void solve(){ memset(sz,0,sizeof(sz)); memset(head,-1,sizeof(head)); top=edgecnt=0; ll res=0; for(int i=1;i<=n;i++)add_edge(i,i,i); for(int i=1;i<=m;i++){ if(Q[i].f==1){ int a=id[Q[i].a],b=id[Q[i].b]; if(sz[a]<sz[b])swap(a,b); stk[++top]=(node){a,b,i}; if(a!=b){ for(int j=head[b];~j;j=e[j].nxt) add_edge(a,e[j].v,b); res+=i; } }else{ int a=Q[i].a; while(a--){ int a=stk[top].a,b=stk[top].b,c=stk[top].c; if(a!=b){ for(int &j=head[a];e[j].pre==b;j=e[j].nxt){ id[e[j].v]=e[j].pre; sz[a]--; } res-=c; } top--; } } if(sz[id[1]]<n)Pt(0); else Pt(res); putchar('\n'); } }}P3;struct P4{ struct edge{ int v,nxt,pre; }e[M<<1]; struct node{ int a,b,c; ll res; }stk[M]; ll res; int top; int sz[N],id[N]; int head[N],edgecnt; void del(int t){ while(t--){ int a=stk[top].a,b=stk[top].b,c=stk[top].c; if(a!=b){ for(int &j=head[a];e[j].pre==b;j=e[j].nxt){ id[e[j].v]=b; sz[a]--; } res-=c; } top--; } } void add_edge(int a,int b,int c){//把b并到a上,b的原来集合为c e[++edgecnt]=(edge){b,head[a],c};head[a]=edgecnt;sz[a]++;id[b]=a; } void solve(){ memset(sz,0,sizeof(sz)); memset(head,-1,sizeof(head)); top=res=edgecnt=0; for(int i=1;i<=n;i++)add_edge(i,i,i); for(int i=1;i<=m;i++){ if(Q[i].f==1){ int a=id[Q[i].a],b=id[Q[i].b]; if(sz[a]<sz[b])swap(a,b); if(a!=b){ for(int j=head[b];~j;j=e[j].nxt) add_edge(a,e[j].v,b); res+=i; } stk[++top]=(node){a,b,i,sz[id[1]]==n?res:0}; }else if(Q[i].f==2){ if(Q[i+1].f==3)top-=Q[i].a; else del(Q[i].a); }else{ if(Q[i-1].f==1)del(1); else top+=Q[i-1].a; } Pt(stk[top].res); putchar('\n'); } }}P4;bool chk1(){ for(int i=1;i<=m;i++) if(Q[i].f!=1)return false; return true;}bool chk2(){ for(int i=1;i<=m;i++) if(Q[i].f==3)return false; return true;}int main(){ int a,b; Rd(n);Rd(m); char s[10]; for(int i=1;i<=m;i++){ scanf("%s",s); if(s[0]=='A'){ Rd(a);Rd(b); Q[i]=(opr){1,a,b}; }else if(s[0]=='D'){ Rd(a); Q[i]=(opr){2,a,0}; }else Q[i]=(opr){3,0,0}; } if(n<=1000&&m<=1000)P1.solve(); else if(chk1())P2.solve(); else if(chk2())P3.solve(); else P4.solve(); return 0;}
还有很多小错误,需要改正!
- 2017/9/2 离线赛
- 2017/8/9 离线赛
- 2017/9/15 离线赛
- 2017-9-24离线赛总结
- 2017-9-25离线赛总结
- 2017-9-26离线赛总结
- 2017-9-28离线赛总结
- 2017-9-29离线赛总结
- 2017-10-9离线赛总结
- 2017-11-9离线赛总结
- 2017/7/15 离线赛
- 2017/7/24 离线赛
- 2017/7/27 离线赛
- 2017/8/5 离线赛
- 2017/8/7 离线赛
- 2017/8/11 离线赛
- 2017/8/14 离线赛
- 2017/8/19 离线赛
- hdu2063(二分图匹配 匈牙利算法模板题)
- 请求网页图片
- HDU
- 数据结构思维 第三章 `ArrayList`
- QToolButton 工具按钮
- 2017/9/2 离线赛
- C# IEnumerable、IEnumerator和yield关键字详解
- SPI总线接口
- doxygen的安装与配置
- 统计学习方法五 决策树分类
- WOJ1133-Candies
- 慕课:Linux达人养成计划I—命令
- python---字典
- VC编译问题:0xC0000005