去JOJ的新生赛以guest的身份打酱油一天

来源:互联网 发布:怎样增加淘宝信用额度 编辑:程序博客网 时间:2024/05/16 10:27

上午:2012级选拔赛 Day I 上(simple problems)

下午:2012级选拔赛 Day I 下(simple searching mechanics)

上午的做的比较水...虽说下午也很水

8道题目场上AC了4道,在比赛后5分钟内AC了一道...可是...可是...尼玛在11:54的时候比赛结束...
计算几何公式搞定二分出答案啊.....
谁叫我起晚了呢......
有3个AK的大牛==
弱货路过...

上午:

A题
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2608&contestid=203
目测是NIM博弈的小变种,暂时还没有接触博弈论==
小推了一下必胜局什么的,没分析出个所以然来
就没推完

B题
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2657&contestid=203
#include<stdio.h>#include<stdlib.h>int cmp(const void *a,const void *b){int *p=(int *)a;int *q=(int *)b;return *p-*q;}int main(){int a[510];int n;while(scanf("%d",&n)!=EOF){int i;for(i=1;i<=n;i++)scanf("%d",&a[i]);qsort(&a[1],n,sizeof(int),cmp);long long res=0;for(i=1;i<n;i++)res+=a[i]*(n-i);printf("%lld\n",res); }return 0;}
排序调库,然后算一下就万事大吉,贪心&排序正确显然...水题一只

C题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=1100&contestid=203
#include<string.h>#include<stdio.h>#include<stdlib.h>char br[10]="<br>";char hr[10]="<hr>";int first=0;int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);char c[10000];int len=0;while(scanf("%s",c)!=EOF){if(strcmp(c,br)==0){first=0;printf("\n");len=0;}else if(strcmp(c,hr)==0){if(first)printf("\n");printf("--------------------------------------------------------------------------------\n");first=0;len=0;}else {len+=strlen(c);if(first)len+=1;if(len<=80){if(!first)first=1;else printf(" ");printf("%s",c);}else {printf("\n%s",c);first=1;len=strlen(c);}}}printf("\n");return 0;}
一开始没注意每行80字符的设置
其实怎么看都是很水的模拟==

D题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2243&contestid=203
#include<stdio.h>#define LL long longint main(){LL n;while(scanf("%lld",&n)!=EOF&&n){LL p=2,res=0;while(n>=p){res+=n/p;p*=2;}printf("%lld\n",res);}return 0;}
这道题就是找规律,其实是看每一位有多少次进位
就是while里面的那部分
一开始int WA,LL %I64d也WA,改成%lld就AC了...
貌似CF忍不了%lld
OJ忍不了%I64d....

E题:
就是刚才说的计算几何
#include<stdio.h>#include<math.h>#define eps 1e-7double PI=2*asin(1),aim;double f(double x){double alpha=asin(x/2);double h=sqrt(1-x*x/4);return PI-alpha+x*h/2-aim;}double abs(double x){if(x>0)return x;return -x;}int main(){double a,b;while(scanf("%lf%lf",&a,&b)!=EOF){double temp;if(b>a){temp=a;a=b;b=temp;}aim=PI*(a)/(a+b);double l=0.0,r=2.0;while(abs(r-l)>eps){double mid=(l+r)/2;if(f(mid)>0)l=mid;else r=mid;}printf("%.4lf\n",l);}return 0;}

推一下公式,二分搞定...万恶的时间...不带提前结束比赛的......

F题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2443&contestid=203
在Lepus上面见过弱一些的10^2级别的数据
O(n^4)的复杂度可以,但是n^3的直接跪,状态转移的O(n)->O(1)的优化想到了
不过没调通,倒是O(n^4)的算法过了Lepus
= =

G题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=1008&contestid=203
我不明白为什么会RE的一道题目,平凡的回文码==居然WA...不能理解...

H题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=1199&contestid=203
就是阶乘最后一位非零数...
#include<stdio.h>int dp[10010];int main(){int i;dp[1]=1;for(i=2;i<=10000;i++){dp[i]=dp[i-1]*i;while(dp[i]%10==0)dp[i]/=10;if(dp[i]>100000)dp[i]%=100000;}int n;while(scanf("%d",&n)!=EOF){printf("%5d -> %d\n",n,dp[n]%10);}}

直接dp取后5位搞定...谁叫数据这么和谐呢....

下午:

例会提前闪掉来做,4of7
是搜索的题目

A题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2534&contestid=204
BFS走迷宫,特殊的怪物处理让他等一回合进队列就好了
不过自己编的好慢...
代码速度不给力啊....
#include<stdio.h>#include<string.h>char map[40][40];int ok[40][40];int bfs[40][40];bool done[40][40];struct point{int x,y;}q[65000],s,t;int ql,qr;bool check_done(point s){return done[s.x][s.y];}point build(int a,int b){point s;s.x=a,s.y=b;return s;}void enq(point s,int t){//printf("enq(%d,%d,%d)=%d\n",s.x,s.y,s.z,t);done[s.x][s.y]=1;bfs[s.x][s.y]=t;qr++; q[qr]=s;}bool check(int x,int y){if(x<0||x>=15)return 0;if(y<0||y>=30)return 0;if(done[x][y])return 0;if(!ok[x][y])return 0;return 1;}int first[40][40];void BFS(int g){if(check_done(t))return;int l=ql,r=qr;int i;for(i=l;i<=r;i++){ql++;int x=q[i].x,y=q[i].y;if(map[x][y]=='M'){if(!first[x][y]){first[x][y]=1;enq(build(x,y),g);continue;}}if(check(x+1,y))enq(build(x+1,y),g);if(check(x-1,y))enq(build(x-1,y),g);if(check(x,y+1))enq(build(x,y+1),g);if(check(x,y-1))enq(build(x,y-1),g);if(ql>qr)return;}BFS(g+1);}int main(){int time;scanf("%d%*c",&time);while(time--){int i,j;for(i=0;i<15;i++)scanf("%s",map[i]);for(i=0;i<15;i++)for(j=0;j<30;j++){if(map[i][j]=='S'){s.x=i;s.y=j;}if(map[i][j]=='T'){t.x=i;t.y=j;}if(map[i][j]=='#')ok[i][j]=0;else ok[i][j]=1;done[i][j]=0;bfs[i][j]=0;first[i][j]=0;}ql=1;qr=0;enq(s,0);BFS(1);int res=bfs[t.x][t.y];if(res)printf("%d\n",res);else printf("-1\n");//printf("%d,%d\n",s.x,s.y);/*for(i=0;i<=t.x;i++){for(j=0;j<=t.y;j++)printf("%4d",bfs[i][j]);printf("\n");}*/}//return main();return 0;}

B题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2431&contestid=204
说白了还是BFS
#include<stdio.h>int bfs[1000010];int done[1000010];int q[1000010];int ql,qr;int x,n;void enq(int x,int t){if(x>=n)x%=n;done[x]=1;bfs[x]=t;qr++;q[qr]=x;}bool check(int x){if(x>=n)x%=n;return done[x];}void BFS(int t){if(check(0))return;int l=ql,r=qr;int i;for(i=l;i<=r;i++){ql++;int x=q[i];if(!check(x+1))enq(x+1,t);if(!check(2*x))enq(2*x,t);if(ql>qr)return;}BFS(t+1);}int main(){while(scanf("%d%d",&x,&n)!=EOF){int i;for(i=0;i<n;i++)bfs[i]=0;for(i=0;i<n;i++)done[i]=0;ql=1;qr=0;enq(x,0);BFS(1);int res=bfs[0];//for(i=0;i<=n;i++)printf("%d ",bfs[i]);printf("\n");printf("%d\n",res);}return 0;}

C题:
uvaoj之前做过原题,直接拷贝AC
#include<stdio.h>char map[110][110];int dp[110][110];int flag[110][110];int m,n;int colour(int x,int y,int k){if(x<0||y<0||x==m||y==n)return 0;if(flag[x][y])return 0;int i,j;//printf("入栈colour(%d,%d,%d):\n",x+1,y+1,k);/*for(i=0;i<m;i++){for(j=0;j<n;j++)printf("%2d ",dp[i][j]);printf("\n");}*/if(map[x][y]=='@'){//printf("dp[%d][%d]=%d\n",x+1,y+1,k);dp[x][y]=k;flag[x][y]=1;}else return 0;colour(x-1,y-1,k);colour(x-1,y,k);colour(x-1,y+1,k);colour(x,y-1,k);colour(x,y,k);colour(x,y+1,k);colour(x+1,y-1,k);colour(x+1,y,k);colour(x+1,y+1,k);//printf("出!\n\n");}int main(){while(scanf("%d%d",&m,&n)!=EOF){if(m==0||n==0)break;getchar();int i,j;for(i=0;i<m;i++)gets(map[i]);for(i=0;i<m;i++)for(j=0;j<n;j++)dp[i][j]=0;for(i=0;i<m;i++)for(j=0;j<n;j++)flag[i][j]=0;int k=0;for(i=0;i<m;i++)for(j=0;j<n;j++){if(!flag[i][j]&&map[i][j]=='@'){++k;colour(i,j,k);}}/*for(i=0;i<m;i++){for(j=0;j<n;j++)printf("%4d",dp[i][j]);printf("\n");}*/printf("%d\n",k);}return 0;}

D题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2062&contestid=204
这算是这场比赛中好好学到的东西了吧
#include<stdio.h>#include<stdlib.h>struct s{int t,x,y;}p[1000000],q[1000000];int cmp(const void *aa,const void *bb){s *a=(s *)aa;s *b=(s *)bb;s p=*a,q=*b;return p.t-q.t;}void gei(s *p,int pp){printf("%d=(%d %d) ",p[pp].t,p[pp].x,p[pp].y);}bool check(int pp,int qq){if(p[pp].t!=q[qq].t)return 0;if(p[pp].x==q[qq].x)return 0;if(p[pp].x==q[qq].y)return 0;if(p[pp].y==q[qq].x)return 0;if(p[pp].y==q[qq].y)return 0;//printf("check(%d %d)=true:",pp,qq);//gei(p,pp);//gei(q,qq);//printf("\n");return 1;}int main(){int a[1010];int n,x;while(scanf("%d%d",&n,&x)!=EOF){int i,j;for(i=1;i<=n;i++)scanf("%d",&a[i]);int pp=0;for(i=1;i<=n;i++){for(j=i+1;j<=n;j++){++pp;p[pp].t=a[i]+a[j];p[pp].x=i;p[pp].y=j;}}qsort(&p[1],pp,sizeof(s),cmp);for(i=1;i<=pp;i++)q[i]=p[pp+1-i];for(i=1;i<=pp;i++)q[i].t=x-q[i].t;qsort(&q[1],pp,sizeof(s),cmp);int pn=pp,pq=1;pp=1;int flag=0;while(pp<=pn&&pq<=pn){if(q[pq].t==p[pp].t){if(check(pq,pp)){flag=1;break;}else {int lp,rp,lq,rq;lp=pp;lq=pq;for(i=lp+1;i<=pn;i++)if(p[i].t!=p[lp].t)break;rp=i-1;for(i=lq+1;i<=pn;i++)if(q[i].t!=q[lq].t)break;rq=i-1;for(i=lp;!flag&&i<=rp;i++)for(j=lq;j<=rq;j++){if(check(i,j)){flag=1;break;}}if(flag)break;pp=rp+1;pq=rq+1;}}else if(q[pq].t>p[pp].t)pp++;else pq++;}if(flag)printf("YES\n");else printf("NO\n");}return 0; }
看数据规模,O(n^4)的枚举一定TLE
想到之前做出来过O(n)级别的求数列是否存在两个数和为x的
排序是O(nlgn)
不过由于是四个数
所以排序就是了O(n^2lgn)

接下来的O(n^2)是我的查找算法,但是里面有可能出现子列O(n^2)级别的while,但是会很快跳出

总体复杂度想不太明白==

思路是构造所有的2个数的和,对2+2做特别判定check

E题
http://acm.jlu.edu.cn/joj/showproblem.php?pid=2578&contestid=204
没有编....从uva拷的ac的码一只PE在G题...不爽就去刀了...
想了下,是DFS,用个5维数组表示状态,编好滚动就好了==
但是貌似-1的退出没太想明白==
之前编的数独也是...
对于这类无解或者多解的题目的特殊情况鸭梨很大==

F题:
http://acm.jlu.edu.cn/joj/showproblem.php?pid=1509&contestid=204
没做的原因同E
汉密尔顿回路,目测是BFS剪枝
但是有TLE的可能...

G题...
http://acm.jlu.edu.cn/joj/showproblem.php?pid=1305&contestid=204
实在是怨念...怎么能钩PE呢....
代码还是放上来...
#include<stdio.h>int num[40];//表示第几位置是什么 int isp[40];int n;int isprime(int x){int i;for(i=2;i*i<=x;i++)if(x%i==0)return 0;return 1;}int place(int k){int i;for(i=1;i<k;i++){if(num[i]==num[k])return 0;}if(k==n){if(!isp[ num[n]+num[1] ])return 0;}if(k>=2)if(!isp[ num[k]+num[k-1] ])return 0;return 1;}void op(int s){int i;if(s>n){int flag=1;for(i=1;i<=n;i++){if(flag)flag=0;else printf(" ");printf("%d",num[i]);}printf("\n");}else {for(i=2;i<=n;i++){num[s]=i;if(place(s))op(s+1);}}}int main(){int k=0; int i;for(i=1;i<=33;i++)isp[i]=isprime(i);while(scanf("%d",&n)!=EOF){if(k++!=0)printf("\n");printf("Case %d:\n",k);if(n%2==1)continue;num[1]=1;op(2);}return 0;}

以上是本人去水...
貌似下午场就我一个guest......
貌似还是被虐的好惨...
fighting
最近有心仪的妹纸了呢!
一切
加油!