Codefoces #354 div.2

第一次晚上打比賽。感覺不好迷迷糊糊。

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);
    }

}


B.

題意:宴會上金字塔酒杯,給出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"));
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章