第一次晚上打比赛。感觉不好迷迷糊糊。
A.
题意:给你一个大小为n的数组,保证数组里的数是1-n.可以任意交换一次位置,求1的位置和n的位置的最大差.
思路:找出1的位置s和n的位置b, 保证b的值比s的值大.ans=Max(abs(b-s),abs(b-1),abs(n-s)).
#include<bits/stdc++.h>
using namespace std;
#define Max(a,b) ((a)>(b)?(a):(b))
const int MAX=105;
int main()
{
int n,a[MAX],b,s;
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
if(a[i]==n)b=i;
if(a[i]==1)s=i;
}
if(b<s)swap(b,s);
int ans=Max(abs(b-s),Max(abs(n-s),abs(b-1)));
printf("%d\n",ans);
}
}
题意:宴会上金字塔酒杯,给出n层数,t时间.第一秒能灌满顶层的杯子,之后每过1s,溢出的部分分别向下层的两个杯子灌1/2.问t时间后灌满的杯子有几个.
思路:n层数,设每个杯子的容量则为2^n,那么一共要灌2^n*t.直接模拟一下.
(比赛的时候不知道怎么回事,有点思路却写不出来,每个杯子容量设为1,用double也可以过,好像没有卡精度这题.)
(wa了几发,没有特判t==0的情况,)
#include<bits/stdc++.h>
using namespace std;
#define Max(a,b) ((a)>(b)?(a):(b))
const int MAX=15;
int main()
{
int n,cap[MAX][MAX],t,ans,vol;
while(~scanf("%d%d",&n,&t))
{
if(t==0){printf("0\n");continue;}
memset(cap,0,sizeof(cap));
cap[1][1]=(int)pow(2.0,n)*t;
//printf("%d\n",cap[1][1]);
vol=(int)pow(2.0,n);
ans=1;
for(int i=2; i<=n; i++)
{
for(int j=1; j<=i; j++)
{
if(j==1&&cap[i-1][j]>=vol)
{
cap[i][j]=(cap[i-1][j]-vol)/2;
//printf("%d %d %d\n",i,j,cap[i][j]);
}
else if(j==i&&cap[i-1][j-1]>=vol)
{
cap[i][j]=(cap[i-1][j-1]-vol)/2;
//printf("%d %d %d\n",i,j,cap[i][j]);
}
else
{
if(cap[i-1][j]>=vol)
cap[i][j]+=(cap[i-1][j]-vol)/2; //不一定两个父杯一定都溢出,这里wa了一次.
if(cap[i-1][j-1]>=vol)
cap[i][j]+=(cap[i-1][j-1]-vol)/2;
//printf("%d %d %d\n",i,j,cap[i][j]);
}
if(cap[i][j]>=vol)
ans++;
//printf("%d %d %d\n",i,j,cap[i][j]);
}
}
/*for(int i=1; i<=n; i++)
{
for(int j=1; j<=i; j++)
printf("%d ",cap[i][j]);
printf("\n");
}*/
printf("%d\n",ans);
}
}
上面的写法是把每个杯子当成子杯子考虑,比较麻烦。
下面的写法是把每个杯子当成父杯子考虑,直接从上往下模拟,代码也比较简短。
#include<stdio.h>
#include<string.h>
const int MAX=15;
double Cap[MAX][MAX];
int main()
{
int n,t;
while(~scanf("%d%d",&n,&t))
{
memset(Cap,0,sizeof(Cap));
Cap[1][1]=t;
int ans=0;
for(int i=1; i<=n; i++)
for(int j=1; j<=i; j++)
if(Cap[i][j]>=1)
{
ans++;
Cap[i+1][j]+=(Cap[i][j]-1)/2;
Cap[i+1][j+1]+=(Cap[i][j]-1)/2;
}
printf("%d\n",ans);
}
}
C.
题意:给一个只含有a,b的字符串,给你为n长度的字符串,可以翻转m个位置(即a->b,b->a),问最长相同的字母的连续子串长度.
思路:第一次听说尺取法,分别考虑全为a的情况和全为b的情况.
http://blog.chinaunix.net/uid-24922718-id-4848418.html这里讲的很详细.
#include<bits/stdc++.h>
using namespace std;
#define Max(a,b) ((a)>(b)?(a):(b))
const int MAX=100005;
int main()
{
int n,k;
char str[MAX];
while(~scanf("%d%d",&n,&k))
{
scanf("%s",str);
int L,R,cnt=k,ans=0,sum=0;
L=R=0;
for(L=0; L<n; L++)
{
while(cnt>=0&&R<n)
{
if(str[R]=='b'&&!cnt)break;
if(str[R]=='b')cnt--;
R++;
//printf("%d %d %d\n",L,R,R-L+1);
ans=Max(ans,R-L);
}
if(str[L]=='b')cnt++;
}
R=L=0;
cnt=k;
// printf("\n");
for(L=0; L<n; L++)
{
while(cnt>=0&&R<n)
{
if(str[R]=='a'&&!cnt)break;
if(str[R]=='a')cnt--;
R++;
//printf("%d %d %d\n",L,R,R-L+1);
ans=Max(ans,R-L);
}
if(str[L]=='a')cnt++;
}
printf("%d\n",ans);
}
//printf("%d\n",ans);
}
D.
题意:给出一个n*m的地图,每个格子代表一个房间,规定房间上哪几个方向有门,之后要想走到邻居房间,那个邻居房间必须也要有通向该房间的门,也可以将地图上各个房间顺时针旋转90,
思路:暴力bfs,首先要确定地图每旋转90度之后的各个房间门的位置,用M[4][1005][1005]来表示,每次扩展四个方向也要判断那个邻居房间是否有通向该房间的门.
(这是我写过最长的bfs了)
<pre name="code" class="cpp">#include<bits/stdc++.h>
using namespace std;
const int MAX=1005;
char M[5][MAX][MAX];
int xt,yt,xm,ym,n,m;
int chan[4][2]= {1,0,-1,0,0,1,0,-1},v[5][MAX][MAX];
struct node
{
int x,y,step,lev;
node(int xx,int yy,int s,int l)
{
x=xx;
y=yy;
step=s;
lev=l;
}
};
bool cmp_top(int l,int xx,int yy)
{
if(M[l][xx][yy]=='|')return 1;
else if(M[l][xx][yy]=='v')return 1;
else if(M[l][xx][yy]=='L'||M[l][xx][yy]=='R'||M[l][xx][yy]=='U'||M[l][xx][yy]=='+')return 1;
else return 0;
}
bool cmp_bottom(int l,int xx,int yy)
{
if(M[l][xx][yy]=='|'||M[l][xx][yy]=='^'||M[l][xx][yy]=='L'||M[l][xx][yy]=='R'||M[l][xx][yy]=='D'||M[l][xx][yy]=='+')
return 1;
else return 0;
}
bool cmp_left(int l,int xx,int yy)
{
if(M[l][xx][yy]=='-'||M[l][xx][yy]=='>'||M[l][xx][yy]=='L'||M[l][xx][yy]=='U'||M[l][xx][yy]=='D'||M[l][xx][yy]=='+')
return 1;
else return 0;
}
bool cmp_right(int l,int xx,int yy)
{
if(M[l][xx][yy]=='-'||M[l][xx][yy]=='<'||M[l][xx][yy]=='R'||M[l][xx][yy]=='U'||M[l][xx][yy]=='D'||M[l][xx][yy]=='+')
return 1;
else return 0;
}
bool ok(int l,int x,int y,int xx,int yy)
{
if(M[l][x][y]=='+')
{
if(xx-x==1)//bottom
{
if(cmp_bottom(l,xx,yy))return 1;
else return 0;
}
if(x-xx==1)//top
{
if(cmp_top(l,xx,yy))return 1;
else return 0;
}
if(y-yy==1)//left
{
if(cmp_left(l,xx,yy))return 1;
else return 0;
}
if(yy-y==1)
{
if(cmp_right(l,xx,yy))return 1;
else return 0;
}
}
if(M[l][x][y]=='-')
{
if(y-yy==1)//left
{
if(cmp_left(l,xx,yy))return 1;
else return 0;
}
if(yy-y==1)
{
if(cmp_right(l,xx,yy))return 1;
else return 0;
}
}
if(M[l][x][y]=='|')
{
if(x-xx==1)//top
{
if(cmp_top(l,xx,yy))
return 1;
else return 0;
}
if(xx-x==1)//bottom
{
if(cmp_bottom(l,xx,yy))return 1;
else return 0;
}
}
if(M[l][x][y]=='^'&&x-xx==1)
{
if(cmp_top(l,xx,yy))return 1;
else return 0;
}
if(M[l][x][y]=='>'&&yy-y==1)
{
if(cmp_right(l,xx,yy))return 1;
else return 0;
}
if(M[l][x][y]=='<'&&y-yy==1)
{
if(cmp_left(l,xx,yy))return 1;
else return 0;
}
if(M[l][x][y]=='v'&&xx-x==1)
{
if(cmp_bottom(l,xx,yy))return 1;
else return 0;
}
if(M[l][x][y]=='L')
{
if(x-xx==1)//top
{
if(cmp_top(l,xx,yy))return 1;
else return 0;
}
if(xx-x==1)//bottom
{
if(cmp_bottom(l,xx,yy))return 1;
else return 0;
}
if(yy-y==1)
{
if(cmp_right(l,xx,yy))return 1;
else return 0;
}
}
if(M[l][x][y]=='R')
{
if(x-xx==1)//top
{
if(cmp_top(l,xx,yy))return 1;
else return 0;
}
if(xx-x==1)//bottom
{
if(cmp_bottom(l,xx,yy))return 1;
else return 0;
}
if(y-yy==1)//left
{
if(cmp_left(l,xx,yy))return 1;
else return 0;
}
}
if(M[l][x][y]=='U')
{
if(xx-x==1)//bottom
{
if(cmp_bottom(l,xx,yy))return 1;
else return 0;
}
if(y-yy==1)//left
{
if(cmp_left(l,xx,yy))return 1;
else return 0;
}
if(yy-y==1)
{
if(cmp_right(l,xx,yy))return 1;
else return 0;
}
}
if(M[l][x][y]=='D')
{
if(x-xx==1)//top
{
if(cmp_top(l,xx,yy))return 1;
else return 0;
}
if(y-yy==1)//left
{
if(cmp_left(l,xx,yy))return 1;
else return 0;
}
if(yy-y==1)
{
if(cmp_right(l,xx,yy))return 1;
else return 0;
}
}
return 0;
}
int bfs(node a)
{
memset(v,0,sizeof(v));
queue<node>Q;
Q.push(a);
v[0][a.x][a.y]=1;
//printf("%d %d %d %d",a.x,a.y,a.step,a.lev);
while(!Q.empty())
{
node now=Q.front();
//printf("%d %d %d %d\n",now.x,now.y,now.step,now.lev);
Q.pop();
if(now.x==xm-1&&now.y==ym-1)
return now.step;
int xx,yy;
for(int i=0; i<4; i++)
{
xx=now.x+chan[i][0];
yy=now.y+chan[i][1];
if(xx<0||xx>=n||yy<0||yy>=m||v[now.lev][xx][yy]||M[now.lev][xx][yy]=='*')continue;
if(ok(now.lev,now.x,now.y,xx,yy))
{//printf("%d %d %d\n",now.lev,xx,yy);
v[now.lev][xx][yy]=1;
Q.push(node(xx,yy,now.step+1,now.lev));
}
}
if(v[0][now.x][now.y]==1&&v[1][now.x][now.y]==1&&v[2][now.x][now.y]==1&&v[3][now.x][now.y]==1)
{//printf("%d %d %d %d\n",v[0][now.x][now.y],v[1][now.x][now.y],v[2][now.x][now.y],v[3][now.x][now.y]);
continue;
}
v[(now.lev+1)%4][now.x][now.y]=1;
Q.push(node(now.x,now.y,now.step+1,(now.lev+1)%4));
}
return -1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0; i<n; i++)
{
scanf("%s",M[0][i]);
for(int j=0; j<m; j++)
{
if(M[0][i][j]=='<')
{
M[1][i][j]='^';
M[2][i][j]='>';
M[3][i][j]='v';
}
else if(M[0][i][j]=='^')
{
M[1][i][j]='>';
M[2][i][j]='v';
M[3][i][j]='<';
}
else if(M[0][i][j]=='>')
{
M[1][i][j]='v';
M[2][i][j]='<';
M[3][i][j]='^';
}
else if(M[0][i][j]=='v')
{
M[1][i][j]='<';
M[2][i][j]='^';
M[3][i][j]='>';
}
else if(M[0][i][j]=='D')
{
M[1][i][j]='L';
M[2][i][j]='U';
M[3][i][j]='R';
}
else if(M[0][i][j]=='L')
{
M[1][i][j]='U';
M[2][i][j]='R';
M[3][i][j]='D';
}
else if(M[0][i][j]=='R')
{
M[1][i][j]='D';
M[2][i][j]='L';
M[3][i][j]='U';
}
else if(M[0][i][j]=='U')
{
M[1][i][j]='R';
M[2][i][j]='D';
M[3][i][j]='L';
}
else if(M[0][i][j]=='+')
{
M[1][i][j]='+';
M[2][i][j]='+';
M[3][i][j]='+';
}
else if(M[0][i][j]=='-')
{
M[1][i][j]='|';
M[2][i][j]='-';
M[3][i][j]='|';
}
else if(M[0][i][j]=='|')
{
M[1][i][j]='-';
M[2][i][j]='|';
M[3][i][j]='-';
}
else if(M[0][i][j]=='*')
{
M[1][i][j]='*';
M[2][i][j]='*';
M[3][i][j]='*';
}
}
}
/*for(int i=0;i<n;i++)
printf("%s\n",M[1][i]);
for(int i=0;i<n;i++)
printf("%s\n",M[2][i]);
for(int i=0;i<n;i++)
printf("%s\n",M[3][i]);*/
scanf("%d%d%d%d",&xt,&yt,&xm,&ym);
int ans=bfs(node(xt-1,yt-1,0,0));
//printf("%d\n",ans);
if(ans!=-1)printf("%d\n",ans);
else printf("-1\n");
}
}
E.
题意:给出n+1个系数,以及(x-k)的k,n+1个系数中可能有“?”表示不确定,系数的index从0开始,
分析第一个样例,n=1,k=2,然后是-1,?;那么一个一元多项式即使 -1*x^0+?*x^1,问在填满所有的不确定系数后,该多项式能不能够整除(x-k)。
如果能整除那么人赢输出yes,反之no;
第一个数是电脑先填的(并不是不确定系数中的第一个数,而是所有系数中的第一个数)。
思路:用数组a存系数。
分两种情况讨论:
1.k==0的时候,a[0]确定的话,为0的时候是yes,不为0的时候是no;
a[0]不确定的话,那么就要争取不确定系数的第一个数必须由人来填,也就是说所有确定的系数的个数必须是奇数。
2.k!=0的时候,如果所有的系数都确定,那么需要满足 该多项式|(x-k) 的条件,即k是该多项式的根,即将k带入多项式求得的数为0.
如果有系数不确定,那么谁填完最后一个数谁就获胜。设最后一个不确定的系数下标为j,a[j]*x^j记作Cj。那么所有确定的系数下标为i(i!=j),a[i]*x^i,他们之和记作Ci。
那如果要满足多项式为0,即使Cj=-Ci=a[j]*x^j,那么a[j]的值就是关键。
#include<bits/stdc++.h>
using namespace std;
const int MAX=100005,INF=0x3f3f3f3f;
int n,k; //起初我将所有变量写在main里面,是错误的,因为写在main里是分配到栈中,可能会爆栈,写到外面是分配到全局数据区。
int a[MAX],cnt=0;
int ten[10]={1,10,100,1000,10000,100000};
char s[5];
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n+1;i++)
{
scanf("%s",s);
if(s[0]=='?')
a[i]=INF;
else
{
int f=0,sum=0;
a[i]=1;
if(s[0]=='-')f=1,a[i]=-1;
for(int j=strlen(s)-1,q=0;j>=f;j--)
sum+=(int)(s[j]-'0')*ten[q++];
a[i]*=sum;
cnt++;
}
}
if(k==0)
{
if(a[0]==INF)
{
if(cnt%2)printf("Yes\n");
else printf("No\n");
}
else
{
if(!a[0])printf("Yes\n");
else printf("No\n");
}
}
else
{
if(cnt<n+1)
{
if((n+1)%2)printf("No\n"); //如果所有的系数的个数为奇数,那么电脑赢。
else printf("Yes\n");
}
else
{
// printf("%d %d",cnt,n+1);
long long sum1=0;
for(int i=n;i>=0;i--)
{sum1=1LL*sum1*k+a[i];
if(abs(sum1)>=1e10) //保证sum的值不会爆long long。
break;
}
printf("%s\n",(sum1?"No":"Yes"));
}
}
}