Codeforces Round #224 (Div. 2)

A题:水题不解释

B题:

因为b是小于1000的,所以b最多有1000种可能。

找到循环节,把当前状态模拟至循环节开始状态。

然后把状态置为减去一定的循环节个数之后的状态。

最后模拟出最终状态。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 1100
#define LL __int64
LL vis[maxn];
int main()
{
    LL a,b,w,x,c;
    while(~scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&w,&x,&c))
    {
        memset(vis,0,sizeof(vis));
        LL times;
        times=0;
        while(b>=x)
        {
            if(c<=a)break;
            b=b-x;
            c--;
            times++;
        }
        if(c<=a)
        {
            cout<<times<<endl;
            continue;
        }
        LL st=0;
        LL l=b;
        LL aj=0;
        while(vis[l]==0)
        {
            vis[l]=1;
            st++;
            if(l>=x)l=l-x;
            else
            {
                l=w-x+l;
                aj++;
            }
        }
        LL ns;
        ns=0;
        if((c-(a+aj))>0)
        {
            ns=(c-a-aj)/(st-aj);
        }
        times+=ns*st;
        c=c-st*ns;
        a=a-aj*ns;

        while(c>a)
        {
            if(b>=x)
            {
                b=b-x;
                c--;
                times++;
            }
            else
            {
                b=w-x+b;
                c--;
                a--;
                times++;
            }
        }
        cout<<times<<endl;
    }
    return 0;
}

c题:水题,依然不解释。只要情况考虑全就行。

d题:
我当时比赛做完前三题之后,时间还剩下46分钟,稍微看了一下d我就去查人去了。。。

没想到d竟然这么水。刚刚看看一下d,20分钟敲出来了,真狠我当初为什么不敲d!

深搜图,找出以每个点为起始点,最长能走的步数maxx。

然后寻找是否存在两个点,使得这两个点为起始点的时候,走路的过程中不回产生碰撞。

如果找到了,输出maxx+maxx。

否则,输出maxx+maxx-1;

#include<string.h>
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 2200
#define INF 100000000
int maps[maxn][maxn];
int val[maxn][maxn];
int vis[maxn][maxn];
int st[maxn][maxn];
int xx[5]={0,0,1,-1};
int yy[5]={-1,1,0,0};
int n,m;
int pan(int x,int y)
{
    if(x<1||x>n||y<1||y>m)return 0;
    return 1;
}
int dfs(int x,int y)
{
    if(pan(x,y)==0)return 0;
    if(vis[x][y])return INF;
    if(val[x][y]!=-1)
    {
        return val[x][y];
    }
    vis[x][y]=1;
    if(maps[x][y]==-1)
    {
        vis[x][y]=0;
        val[x][y]=0;
        return 0;
    }
    else
    {
        int t=dfs(x+xx[maps[x][y]],y+yy[maps[x][y]])+1;
        vis[x][y]=0;
        val[x][y]=t;
        return t;
    }
}
int dos(int x,int y,int step)
{
    if(st[x][y]!=-1)
    {
        if(st[x][y]!=step||maps[x][y]==-1)return 1;
        else return 0;
    }
    if(maps[x][y]==-1)
    {
        st[x][y]=step;
        return 1;
    }
    else
    {
        st[x][y]=step;
        return dos(x+xx[maps[x][y]],y+yy[maps[x][y]],step+1);
    }
}
int main()
{
    int i,j;
    char str[19999];
    while(~scanf("%d%d",&n,&m))
    {
        memset(val,-1,sizeof(val));
        memset(vis,0,sizeof(vis));
        memset(st,-1,sizeof(st));
        for(i=1;i<=n;i++)
        {
            scanf("%s",str);
            for(j=1;j<=m;j++)
            {
                if(str[j-1]=='#')maps[i][j]=-1;
                else if(str[j-1]=='^')maps[i][j]=3;
                else if(str[j-1]=='v')maps[i][j]=2;
                else if(str[j-1]=='<')maps[i][j]=0;
                else if(str[j-1]=='>')maps[i][j]=1;
            }
        }
        int maxx;
        maxx=0;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(val[i][j]!=-1)continue;
                if(maps[i][j]==-1)continue;
                int fs=dfs(i,j);
                if(fs>=INF)break;
                maxx=max(maxx,fs);
            }
            if(j<=m)break;
        }
        if(i<=n)
        {
            cout<<"-1"<<endl;
            continue;
        }
        if(maxx==0)
        {
            cout<<"0"<<endl;
            continue;
        }
        int ll=0;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(val[i][j]==maxx)
                {
                    if(dos(i,j,1))
                    {
                        ll++;

                        if(ll>1)
                        {
                            cout<<maxx+maxx<<endl;
                            break;
                        }
                    }
                }
            }
            if(j<=m)break;
        }
        if(i>n)cout<<maxx+maxx-1<<endl;
    }
    return 0;
}




















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值