第一次晚上打比賽。感覺不好迷迷糊糊。
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"));
}
}
}