Codeforces Round #188 (Div. 2)

A:有一个序列,前面是1~n的奇数 ,后面是1~n的偶数,然后输入一个下标(从1开始),输出这个下标在序列对应的数字.

    所以只需要判断这个数是奇数还是偶数,并且是奇数的第几个或者偶数的第几个,然后等差数列求某一项而已.


B.求给定的串里有多少个子串是以"heavy"开始,以"metal"结束的.

   先暴力求出"heavy"出现的位置,存入num1;再暴力求出"metal"出现的位置,存入num2,显然num1和num2都是升序的.即求对于num1的一个元素,在num2中有多少个大于他的,再取和.

    num1:0,1,2,......i,...j,......n1;

    num2:0,1,2........p.....q....n2;

显然如果p>i,则i和i之前的"heavy"都可以和p组成我们需要的,然后就接着看q,既然q>p,那么满足p的,肯定都能满足q.


C:直接给代码吧,比文字更好理解.


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
__int64 x,y,m;
int main()
{
    while(~scanf("%I64d%I64d%I64d",&x,&y,&m))
    {
        if(max(x,y)>=m)
        {
            printf("0\n");
        }
        else if(max(x,y)<=0)
        {
            printf("-1\n");
        }
        else
        {
            if(x>y) swap(x,y);
            __int64 M=min(y,m);
            __int64 t=(M-x)/y+((M-x)%y!=0);
            x+=t*y;
            if(M==y&&x<m)
            {
                while(x<m&&y<m)
                {
                    if(x+x+y>y+x+y)
                    {
                        y=x+y;
                    }
                    else
                    x=x+y;
                    t++;
                }
            }
            printf("%I64d\n",t);
        }
    }
    return 0;
}



D:需要明白一点,最后的情形基本是均匀的,而30000<180*180,即使一个坐标一只蚂蚁,那数组也不到180*180,然后就是爆搜.

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define N 180
int inq[N][N],ans[N][N];//inq标记此点是否在queue中,ans存答案
int n,t,x,y;
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
bool is_ok(int x,int y)
{
    if(x>=0&&y>=0&&x<180&&y<180) return 1;
    return 0;
}
struct node
{
    int x,y;
};//点不能重复入队,但可以在不入队的情况下,修改ans的值
void bfs()
{
    queue<node>q;
    node vn,vw;
    vn.x=90;
    vn.y=90;
    inq[vn.x][vn.y]=1;
    ans[vn.x][vn.y]=n;
    if(ans[vn.x][vn.y]>=4)//只有一个点的数量>=4时,并且没有在队中,才能入队
    q.push(vn);
    while(!q.empty())
    {
        vn=q.front();
        q.pop();
        inq[vn.x][vn.y]=0;
        int p=ans[vn.x][vn.y]/4;
        ans[vn.x][vn.y]-=4*p;//一开始写成-4了,WA了,此时每次跑出去的应该是<=ans中最大的4的倍数
        for(int i=0;i<4;i++)
        {
            int a=vn.x+dx[i];
            int b=vn.y+dy[i];
            if(is_ok(a,b))
            {
                ans[a][b]+=p;
                if(ans[a][b]>=4&&inq[a][b]==0)//一开始忘记判断inq[a][b]==0了,出现了不停的重复入队,然后就MLE了,好像SPFA呀
                {
                    vw.x=a;
                    vw.y=b;
                    inq[a][b]=1;
                    q.push(vw);
                }
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&t))
    {
        memset(inq,0,sizeof(inq));
        memset(ans,0,sizeof(ans));
        bfs();
        while(t--)
        {
            scanf("%d%d",&x,&y);
            x+=90;
            y+=90;
            if(x<0||x>=180||y<0||y>=180)
            printf("0\n");
            else
            {
                printf("%d\n",ans[x][y]);
            }
        }
    }
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值