『UVA 1622』机器人

转载声明:http://www.cnblogs.com/137033036-wjl/p/4945009.html

题意:给出n*m个格子,每个格子里有一个机器人,可以执行东南西北四种指令,但是移动出格就会爆炸。给出四种指令的个数,求最多完成多少次指令。

个人感想:实在令人崩溃的问题,处理的细节也是挺多的,我是不断的wa了…之后只能原封不动的套上上面的模板了,我是不知道我为什么错了我的想法几乎和上面一模一样,只是我在判断我是以上下为基准,先做上下移动,再做左右,主要的是多的来的上nor,会影响到左右来回循环的影响,然后我枚举不同的nor,再加上左右的来回移动,再加上剩下的上和左右的移动,但是不知道为什么还是wa了,实在崩溃,太废时了想这道题,有空再验证吧.没心思做这种题了…做这种题,一旦wa了,感觉连验证都不知道如何验证是好,手写的情况又多,实在头疼…

这是我wa的代码:

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */
//#define OUT
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define Clear(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
int N,M;
long long  nor,sou,eas,wes;
long long ans;
bool flag=true;
long long solve(int tnor)
{
    int lnor=nor-tnor;

    int teas=eas;
    int twes=wes;

    long long ans=0;
    int n=N;
    int m=M;

    if(n>=tnor)
    {
        ans+=(long long)m*(n*tnor-tnor*(tnor-1)/2);
        n-=tnor;
    }
    else
    {
        return (long long)(m*(n*n-n*(n-1)/2));
    }


    if(teas)
    {
       ans+=(long long)(m*n);
       m--;
       twes--;
    }
    if(teas)
    {
        ans+=(long long)(n*m)*(2*teas-1);
        twes-=(teas-1);
    }
    if(twes&&teas)
    {
        ans+=(long long)(n*m);
        twes--;
    }


    while(twes&&m&&lnor&&n)
    {
        if(n>m)
        {
            ans+=(long long)n*m;
            n--;
            lnor--;
        }
        else
        {
            ans+=(long long)n*m;
            m--;
            twes--;
        }
    }

    while(twes&&m)
    {
        ans+=(long long)n*m;
        m--;
        twes--;
    }

    while(lnor&&n)
    {
        ans+=(long long)n*m;
        n--;
        lnor--;
    }

    return ans;
}


int main()
{
#ifdef OUT
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif
    int cas=0;
    while(scanf("%d%d",&N,&M),N+M)
    {
        cas++;
        printf("Case %d: ",cas);

        ans=0;
        cin>>nor>>sou>>wes>>eas;

        if(nor<sou) swap(nor,sou);
        if(wes<eas) swap(wes,eas);

        long long t1=N+(M-1)*N*eas*2+(M-1)+(M-1)*(N-1)*sou*2;
        long long t2=M+M*(N-1)*sou*2+(N-1)+(M-1)*(N-1)*eas*2;

        if(wes-eas)
        {
            t1+=(M-1)*N;
            t2+=(M-1)*(N-1);
        }
        if(nor-sou)
        {
            t1+=(M-1)*(N-1);
            t2+=M*(N-1);
        }
        if(t1>t2)
        {
            swap(N,M);
            swap(nor,wes);
            swap(eas,sou);
        }

        if(sou)
        {
            ans+=(long long)(N*M);
            nor--;
            N--;
        }

        if(sou)
        {
            ans+=(long long)(N*M)*(2*sou-1);
            nor-=(sou-1);
        }

        if(nor&&sou)
        {
            ans+=(long long)(N*M);
            nor--;
        }


        long long temp=0;
        for(int i=0;i<=nor;i++)
        {
            long long t=solve(i);
            if(t>=temp)
            {
                temp=t;
            }
        }
        ans+=temp;

        cout<<ans<<endl;

    }
    return 0;
}

分析:贪心.
正确代码:

/* Author:GavinjouElephant
 * Title:
 * Number:
 * main meanning:
 *
 *
 *
 */
//#define OUT
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define Clear(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
long long  N,M;
long long  nor,sou,eas,wes;
long long ans;


int main()
{
#ifdef OUT
    freopen("coco.txt","r",stdin);
    freopen("lala.txt","w",stdout);
#endif

    long long  t=0;
    while(cin>>N>>M,N||M)
    {
        t++;
        ans=0;
        cin>>nor>>sou>>wes>>eas;

        if(nor<sou) swap(nor,sou);
        if(wes<eas) swap(wes,eas);

        long long t1=N+(M-1)*N*eas*2+(M-1)+(M-1)*(N-1)*sou*2;
        long long t2=M+M*(N-1)*sou*2+(N-1)+(M-1)*(N-1)*eas*2;

        if(wes-eas)
        {
            t1+=(M-1)*N;
            t2+=(M-1)*(N-1);
        }
        if(nor-sou)
        {
            t1+=(M-1)*(N-1);
            t2+=M*(N-1);
        }
        if(t1<t2)
        {
            swap(N,M);
            swap(nor,wes);
            swap(eas,sou);
        }

        bool flag=true;

        if(eas)
        {
            ans+=N+(M-1)*N*eas*2;
            wes-=eas;
            eas=0;
            M--;
            flag=false;
        }
        if(wes)
        {
            ans+=M*N;
            --wes;
            if(flag) --M;
        }
        wes=min(M,wes);
        while(wes||nor)
        {
            if(sou)
            {
                long long  t1=M*N+(N-1)*M*2*sou;
                long long  t2=M*N+(M-1)*N+(M-1)*(N-1)*(2*sou-1);

                if(nor-sou)
                {
                    t1=M*N+(N-1)*M*(2*sou+1);
                    t2=M*N+(M-1)*N+(M-1)*(N-1)*2*sou;
                }
                if(t1>t2||!wes)
                {
                    ans+=M+M*(N-1)*sou*2;
                    nor-=sou;
                    sou=0;
                    --N;
                    if(nor)ans+=M*N,--nor;
                    nor=min(N,nor);
                }
                else
                {
                    ans+=M*N;
                    --M;
                    --wes;
                }

            }
            else if(!wes)
            {
                ans+=M*nor*(2*N-nor+1)/2,nor=0;
            }
            else if(!nor)
            {
                ans+=N*wes*(2*M-wes+1)/2,wes=0;
            }
            else
            {
                ans+=M*N;
                if(M>N)--M,--wes;
                else --N,--nor;
            }
        }
        printf("Case %d: ",t);
        printf("%lld\n",ans);

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值