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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值