2017"百度之星"程序设计大赛-初赛(A) 比赛总结
来源:互联网 发布:网络彩票停售 编辑:程序博客网 时间:2024/05/21 09:18
T1:小C的倍数问题(hdu6108)
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6108
题目分析:最水的一题,考场上最多人AC。题目是要我们求有多少个B使得
与
是等价的。我们可以对上下两式做差,得到:
由于
所以B是P-1的因数,直接用
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;int t,p;int main(){ freopen("1001.in","r",stdin); freopen("1001.out","w",stdout); scanf("%d",&t); while (t--) { scanf("%d",&p); p--; int k=(int)floor( sqrt( (double)p )+1e-8 ),ans=0; for (int i=1; i<=k; i++) if (p%i==0) { ans++; if (i*i!=p) ans++; } printf("%d\n",ans); } return 0;}
T2:数据分割(hdu6109)
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6109
题目分析:一道并查集好题啊,明明是这么简单的算法考场上却少有人AC。先讲一下我考试时候的想法:假设所有
后来看了网上大神的做法,大概也是并查集+启发式合并。对于
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=100100;struct edge{ int obj; edge *Next,*rev;} e[maxn<<1];edge *head[maxn];int cur=-1;int fa[maxn];int Size[maxn];int sak[maxn<<1];int tail=0;int ans[maxn];int num=0;int n;void Up(int x){ if (x==fa[x]) return; Up(fa[x]); fa[x]=fa[ fa[x] ];}void Delete(){ while (tail) { int x=sak[tail]; head[x]=NULL; fa[x]=x; Size[x]=0; tail--; }}void Add(int x,int y){ cur++; e[cur].obj=y; e[cur].rev=&e[cur+1]; e[cur].Next=head[x]; head[x]=e+cur; cur++; e[cur].obj=x; e[cur].rev=&e[cur-1]; e[cur].Next=head[y]; head[y]=e+cur;}int main(){ freopen("2.in","r",stdin); freopen("2.out","w",stdout); scanf("%d",&n); for (int i=1; i<=n; i++) head[i]=NULL,fa[i]=i; for (int i=1; i<=n; i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if (x==y) if (z) continue; else { Delete(); ans[++num]=i; continue; } sak[++tail]=x; sak[++tail]=y; Up(x); Up(y); if (!z) if (fa[x]==fa[y]) ans[++num]=i,Delete(); else Add(fa[x],fa[y]),Size[ fa[x] ]++,Size[ fa[y] ]++; else { if (fa[x]==fa[y]) continue; if (Size[ fa[x] ]>Size[ fa[y] ]) swap(x,y); edge *q=NULL; bool sol=true; for (edge *p=head[ fa[x] ]; p; p=p->Next) if (p->obj==fa[y]) { ans[++num]=i; Delete(); sol=false; break; } else p->rev->obj=fa[y],q=p; if (!sol) continue; if (q) { q->Next=head[ fa[y] ]; head[ fa[y] ]=head[ fa[x] ]; } Size[ fa[y] ]+=Size[ fa[x] ]; fa[ fa[x] ]=fa[y]; } } printf("%d\n",num); for (int i=1; i<=num; i++) printf("%d\n",ans[i]-ans[i-1]); return 0;}
T3:路径交(hdu6110)
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6110
题目分析:在我做这题之前网上好像还没有人写这题的总结,所以我并不知道是否有人用比我的方法更优的解法,我的方法是
首先我们需要知道怎么用
然后知道了树上路径求交,剩下的事就简单了。我们发现路径交集是满足区间信息加法的,于是可以用一个ST表存储路径交。设f[i][j]为第
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=500100;const int maxl=22;typedef long long LL;struct data{ int val; data *dNext;} cnt[maxn];struct edge{ int obj; LL len; edge *Next;} e[maxn<<1];edge *head[maxn];int cur=-1;int dep[maxn];LL dis[maxn];int fa[maxn][maxl];int L[maxn][maxl];int R[maxn][maxl];int tp[6];int P[maxn];int max_dep=0;int l[maxn];int r[maxn];int n,m,q;int Read(){ int x=0; char c=getchar(); while ( c<'0' || '9'<c ) c=getchar(); while ( '0'<=c && c<='9' ) x=(x<<3)+(x<<1)+(c-'0'),c=getchar(); return x;}void Add(int x,int y,LL z){ cur++; e[cur].obj=y; e[cur].len=z; e[cur].Next=head[x]; head[x]=e+cur;}int Max(int x,int y){ return ((x>y)? x:y);}void Dfs(int node){ max_dep=Max(max_dep,dep[node]); for (edge *p=head[node]; p; p=p->Next) { int son=p->obj; if (son!=fa[node][0]) { fa[son][0]=node; dep[son]=dep[node]+1; dis[son]=dis[node]+p->len; Dfs(son); } }}void Make_fa(){ for (int j=1; j<=P[max_dep]+1; j++) for (int i=1; i<=n; i++) fa[i][j]=fa[ fa[i][j-1] ][j-1];}void Swap(int &x,int &y){ int z=x; x=y; y=z;}int Lca(int u,int v){ if (dep[u]<dep[v]) Swap(u,v); for (data *p=&cnt[ dep[u]-dep[v] ]; p!=cnt; p=p->dNext) u=fa[u][p->val]; if (u==v) return u; int mj=P[ dep[u] ]; for (int j=mj; j>=0; j--) if ( fa[u][j]!=fa[v][j] ) u=fa[u][j],v=fa[v][j]; return fa[u][0];}bool Check(int x,int a,int b,int c){ int p=Lca(a,x); int q=Lca(b,x); return ( ( p==c && q==x ) || ( q==c && p==x ) );}bool Judge(int a,int b,int c,int d,int lca){ return ( Check(a,c,d,lca) && Check(b,c,d,lca) );}void Get(int a,int b,int c,int d,int &u,int &v){ tp[0]=Lca(a,b); tp[1]=Lca(a,c); tp[2]=Lca(a,d); tp[3]=Lca(b,c); tp[4]=Lca(b,d); tp[5]=Lca(c,d); int now_len=0; for (int i=0; i<5; i++) if (tp[i]) for (int j=i+1; j<6; j++) if (tp[j]) { int k=Lca(tp[i],tp[j]); LL temp=dep[ tp[i] ]+dep[ tp[j] ]-2LL*dep[k]; if (temp<=now_len) continue; bool f=Judge(tp[i],tp[j],a,b,tp[0]); if (!f) continue; f&=Judge(tp[i],tp[j],c,d,tp[5]); if (f) u=tp[i],v=tp[j],now_len=temp; }}int main(){ freopen("3.in","r",stdin); freopen("3.out","w",stdout); P[0]=-1; for (int i=1; i<maxn; i++) { P[i]=P[i>>1]+1; int x=(i&(-i)); cnt[i].dNext=&cnt[i-x]; while (x) cnt[i].val++,x>>=1; cnt[i].val--; } n=Read(); for (int i=1; i<=n; i++) head[i]=NULL; for (int i=1; i<n; i++) { int x=Read(),y=Read(),z=Read(); Add(x,y,z); Add(y,x,z); } fa[1][0]=1; Dfs(1); Make_fa(); m=Read(); for (int i=1; i<=m; i++) l[i]=Read(),r[i]=Read(); for (int i=1; i<m; i++) Get(l[i],r[i],l[i+1],r[i+1],L[i][0],R[i][0]); for (int j=1; j<=P[m]; j++) for (int i=1; i<=m; i++) if ( i+(1<<j)<=m ) { int mid=i+(1<<(j-1)); int a=L[i][j-1]; int b=R[i][j-1]; int c=L[mid][j-1]; int d=R[mid][j-1]; if ( a && b && c && d ) Get(a,b,c,d,L[i][j],R[i][j]); } q=Read(); for (int i=1; i<=q; i++) { int x=Read(),y=Read(); int u=0,v=0; if (x==y) u=l[x],v=r[x]; else { int z=P[y-x]; y-=(1<<z); if ( L[x][z] && R[x][z] && L[y][z] && R[y][z] ) Get(L[x][z],R[x][z],L[y][z],R[y][z],u,v); } if ( u && v ) { int w=Lca(u,v); LL ans=dis[u]+dis[v]-2LL*dis[w]; printf("%I64d\n",ans); } else printf("0\n"); } return 0;}
T4:迷宫出逃(hdu6111)
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6111
题目分析:这题我考试的时候看完题就没去想,因为考场上没有人AC,而且当时我剩余的时间也不是很充裕。后来比赛结束之后我又重新想了想,感觉只会宽搜的做法,而且还要
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=70;const int M=100007;const long long M1=998353244;const long long M2=1000000007;const long long M3=133333331;const int u[4]={0,1,0,-1};const int v[4]={1,0,-1,0};typedef unsigned long long ULL;struct data{ ULL map; bool key; int X,Y;} Hash[M];data que[M];int step[M];int head,tail;int a[maxn][maxn];char s[maxn];int sx,sy,kx,ky,ex,ey;int t,n,m,ans;void Push(int x){ ULL tp=que[x].map%(unsigned long long)M; long long y=tp; y=(y+(long long)que[x].key*M1)%M; y=(y+(long long)que[x].X*M2)%M; y=(y+(long long)que[x].Y*M3)%M; while ( Hash[y].X!=-1 ) { y++; if (y==M) y=0; } Hash[y]=que[x];}ULL Get(int x,int y){ x=x*m+y; x=n*m-x-1; ULL tp=1; tp<<=x; return tp;}bool Check(data x){ ULL tp=x.map%(unsigned long long)M; long long y=tp; y=(y+(long long)x.key*M1)%M; y=(y+(long long)x.X*M2)%M; y=(y+(long long)x.Y*M3)%M; while ( Hash[y].X!=-1 && ( Hash[y].map!=x.map || Hash[y].key!=x.key || Hash[y].X!=x.X || Hash[y].Y!=x.Y ) ) { y++; if (y==M) y=0; } if (Hash[y].X==-1) return false; return true;}void Bfs(){ for (int i=0; i<M; i++) Hash[i].X=-1; head=0,tail=1; que[1].map=0; for (int i=0; i<n; i++) for (int j=0; j<m; j++) { int x=a[i][j]; if (x==2) x=0; que[1].map=( (que[1].map<<1)|x ); } que[1].key=0; que[1].X=sx; que[1].Y=sy; Push(1); while (head<tail) { head++; int x=que[head].X,y=que[head].Y; for (int i=0; i<4; i++) { int dx=x+u[i],dy=y+v[i]; if ( dx<0 || n<=dx || dy<0 || m<=dy ) continue; if ( !( que[head].map & Get(dx,dy) ) ) { if ( dx==kx && dy==ky ) { data p; p.map=que[head].map; p.key=1; p.X=dx; p.Y=dy; if ( !Check(p) ) que[++tail]=p,step[tail]=step[head]+1, Push(tail); } if ( dx==ex && dy==ey && que[head].key ) { ans=step[head]+1; return; } if ( a[dx][dy]==2 ) { data p; p.map=que[head].map; if (dx) p.map^=Get(dx-1,dy); if (dy) p.map^=Get(dx,dy-1); if (dx<n-1) p.map^=Get(dx+1,dy); if (dy<m-1) p.map^=Get(dx,dy+1); p.key=que[head].key; p.X=dx; p.Y=dy; if ( !Check(p) ) que[++tail]=p,step[tail]=step[head]+1, Push(tail); } if ( a[dx][dy]!=2 ) { data p; p.map=que[head].map; p.key=que[head].key; p.X=dx; p.Y=dy; if ( !Check(p) ) que[++tail]=p,step[tail]=step[head]+1, Push(tail); } } } }}int main(){ freopen("4.in","r",stdin); freopen("4.out","w",stdout); scanf("%d",&t); for (int g=1; g<=t; g++) { printf("Case #%d:\n",g); scanf("%d%d",&n,&m); ans=-1; for (int i=0; i<n; i++) { scanf("%s",&s); for (int j=0; j<m; j++) { if (s[j]=='x') a[i][j]=1; else if (s[j]=='*') a[i][j]=2; else { if (s[j]=='S') sx=i,sy=j; if (s[j]=='K') kx=i,ky=j; if (s[j]=='E') ex=i,ey=j; a[i][j]=0; } } } Bfs(); printf("%d\n",ans); } return 0;}
T5:今夕何夕(hdu6112)
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6112
题目分析:这应该是本场比赛最没有技术含量的一题,也是最多WA的一题。总的来说就是看输入的日期和2月29号的关系,如果在2月29号之前,则到下一年的同一天为止经过的天数由今年是不是闰年决定;在2.29之后则要看下一年是不是闰年;如果刚好是2.29则找到下一个闰年,看看中间经过了多少天。
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;int t,y,m,d;bool Judge(int x){ if ((x%100)==0) return ((x%400)==0); return ((x%4)==0);}int Get(int x){ if ( Judge(x) ) return (366%7); return (365%7);}int main(){ freopen("1005.in","r",stdin); freopen("1005.out","w",stdout); scanf("%d",&t); while (t--) { scanf("%d-%d-%d",&y,&m,&d); int k=0; if ( m<2 || ( m==2 && d<29 ) ) { k=(k+Get(y))%7; y++; while (k) { k=(k+Get(y))%7; y++; } printf("%d\n",y); } else if ( m==2 && d==29 ) { if ( Judge(y+4) ) k=(k+1461)%7; else k=(k+1460)%7; y+=4; while ( k || (!Judge(y)) ) { if ( Judge(y+4) ) k=(k+1461)%7; else k=(k+1460)%7; y+=4; } printf("%d\n",y); } else { y++; k=(k+Get(y))%7; while (k) { y++; k=(k+Get(y))%7; } printf("%d\n",y); } } return 0;}
T6:度度熊的01世界(hdu6113)
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6113
题目分析:这题一开始以为很难,后来发现就是个搜索……我们先深搜一遍看看1是不是只组成了1个连通块。然后搜一遍所有0组成的连通块,如果它碰到了地图的边界,那么它就不被1所完全包含,否则它被1组成的连通块完全包含。最后看看有几个被1包含的0组成的连通块即可,还要注意一下没有1的情况。
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=110;const int u[4]={0,1,0,-1};const int v[4]={1,0,-1,0};bool f[maxn][maxn];bool vis[maxn][maxn];char s[maxn];int num1;int n,m;bool Dfs(int x,int y,int z){ bool fl=true; if ( x==1 || x==n || y==1 || y==m ) fl=false; if (f[x][y]) num1--; vis[x][y]=true; for (int i=0; i<=3; i++) { int dx=x+u[i],dy=y+v[i]; if ( 1<=dx && dx<=n && 1<=dy && dy<=m && f[dx][dy]==z && !vis[dx][dy] ) fl&=Dfs(dx,dy,z); } return fl;}int main(){ freopen("1006.in","r",stdin); freopen("1006.out","w",stdout); scanf("%d%d",&n,&m); while ( n && m ) { num1=0; for (int i=1; i<=n; i++) { scanf("%s",&s); for (int j=1; j<=m; j++) { f[i][j]=s[j-1]-'0'; if (f[i][j]) num1++; } } memset(vis,false,sizeof(vis)); int yy=0; for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) if ( !vis[i][j] && f[i][j] ) { Dfs(i,j,1); yy++; } if (yy!=1) printf("-1\n"); else { int x=0; for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) if ( !vis[i][j] ) { bool k=Dfs(i,j,0); if (k) x++; } if (!x) printf("1\n"); else if (x==1) printf("0\n"); else printf("-1\n"); } n=0,m=0; scanf("%d%d",&n,&m); } return 0;}
总结:这次比赛考的真的很差,完全就是发挥失常。比赛开始10分钟,我浏览了一遍所有题目,先切T5。由于越快AC得分越高,我一改往常的写代码风格,用前所未有的手速敲出T5的code,然后错漏百出,有很多细节没有考虑。我写的程序不停地WA,调来调去调不过,然后我去看了看ranklist,发现好多人AC了两题了!我心里越来越慌,更加发现不了程序的错,后来甚至找了机房里和我一起考比赛的tututu的代码来对拍才发现错。由于评测姬那蜗牛般的速度,我看到自己T5显示AC的时候比赛已经过去了75min……现在想来当时实在是太紧张了,导致代码写错反而浪费更多时间。
然后用5min写了T1大水题的code(然而显示AC又过了15min)。写了一发T6,15:50交了程序,然后想T2,T3,T4,发现一题都不会。4:20的时候我又看了看我T6的code,发现没有特判地图中没有1的情况,无奈又交了一发(此时我15:50交的代码还没开始评测)。比赛一结束不知为何评测姬就跑得飞快了,然后我看到我T6WA了……我赶紧看看代码,发现本应如果没有被1包含的0的连通块输出1,有一个则输出0,而我将它们搞反了……其实本来这是连样例都不过的,但我当时心态爆炸,见到样例输出一个1,一个0,一个-1就直接交了……由于只AC了两题,而且T5WA了很多次,直接rk1200多。幸好第二天的初赛B吸取了教训稳定了心态,回到了rk120多,不然连复赛都进不了了QAQ。以后参加这种重大的ACM赛制的比赛一定要稳中求进,不要贪快,平时也要锻炼自己快速写对code的能力。还有ranklist只是用来参考下一步该做哪题,绝不能因为看见别人AC了这么多题就乱了自己的节奏。
- 2017"百度之星"程序设计大赛-初赛(A) 比赛总结
- 2017"百度之星"程序设计大赛-资格赛 比赛总结
- 百度之星程序设计大赛初赛
- 2017百度之星程序设计大赛 总结
- 2005年百度之星程序设计大赛初赛题目(1)
- 2005年百度之星程序设计大赛初赛题目(2)
- 百度之星2009程序设计大赛 初赛第一场试题
- 2006 年百度之星程序设计大赛初赛题目 5
- 2005年百度之星程序设计大赛试题初赛题目
- 2015年百度之星程序设计大赛 - 初赛(1)
- 2015年百度之星程序设计大赛 - 初赛(1) 【题解】
- 2015年百度之星程序设计大赛 - 初赛(2)【题解】
- 2015年百度之星程序设计大赛 - 初赛(1)
- HDU-2017"百度之星"程序设计大赛-初赛(B)-1001-Chess
- HDU-2017"百度之星"程序设计大赛-初赛(B)-1006-小小粉丝度度熊
- HDU-2017"百度之星"程序设计大赛-初赛(B)-补题
- HDU-2017"百度之星"程序设计大赛-初赛(B)-1005-度度熊的交易计划
- HDU-2017"百度之星"程序设计大赛-初赛(B)-1002-Factory
- 数据结构学习(1) c语言中关于srand((unsigned)time(NULL))和rand的区别
- Java代码点和代码单元及其区别
- RobotFramework的奇淫技巧——变量
- HDU 6127 Hard challenge(极角排序+模拟)
- 图片与Base64数据转换存储
- 2017"百度之星"程序设计大赛-初赛(A) 比赛总结
- cookie_session的详细用法
- 桥接模式
- 乙级1061. 判断题(15)
- 大数据平台搭建(hadoop+spark)
- ubuntu16.04上安装mysql
- 数据库事务的四大特性以及事务的隔离级别
- 布隆过滤器-原理介绍
- Hdu6129 Just do it(2017多校第7场)