上午: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 long
int 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-7
double 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
最近有心仪的妹纸了呢!
一切
加油!