Smzzl with Greedy Snake(hdu7051)

原题链接

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

2
0 0 0
2
-1 -1
1 1
0 0 2
5
-1 2
2 4
3 -5
4 -2
5 0

输出样例

ufufuffuff
cfcffffcffffcfffffffffufufffffcf

题目大意:模拟贪吃蛇游戏的机制,输出吃完所有食物的最小移动方案。

标准的小型模拟题(只是码量比较多),每吃完一个食物后会刷出一个新食物的坐标,因此可根据食物和蛇的位置关系分为九大类:左上、右上、左下、右下、重合、正上、正下、正左、正右。而由于蛇头的朝向共有四种,因此总共可分为 4 * 9 种情况进行讨论,全部模拟即可。

请添加图片描述

如图例,当蛇与食物的横纵坐标均不相同时,最短路径为蓝线(先横再竖)和绿线(先竖再横)两种走法,此时耗费的步数是相同的,因此需要考虑的因素为蛇头的方向。在该种情况下,当蛇头为 0 时,显然可不用转头直接前进走绿线;当蛇头为 1 时,显然可不用转头直接前进走蓝线;当蛇头为 2 时,显然逆时针旋转一次走蓝线比顺时针旋转两次走绿线的操作次数要小;同理得 3 的最佳决策是顺时针旋转一次。

需要注意的是,每结束一个食物后都需要更新现状态蛇头的朝向和当前蛇的坐标。如该图中走蓝线则蛇头朝向为 0,走绿线则蛇头朝向为 1。

参考代码

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int t;
    cin>>t;
    int a,b,d,k,x,y,heng,shu;
    while(t--){
        cin>>a>>b>>d;
        cin>>k;
        for(int j=1;j<=k;j++){
            cin>>x>>y;
            heng=x-a,shu=y-b;
            a=x,b=y;
            if(heng>0&&shu>0){//右上 
                if(d==0||d==3){
                    if(d==3)
                        cout<<'c';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    cout<<'c';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    d=1;
                }
                else if(d==1||d==2){
                    if(d==2)
                        cout<<'u';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    cout<<'u';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    d=0;
                }
            }
            
            else if(heng>0&&shu<0){//右下 
                shu=-shu;
                if(d==2||d==3){
                    if(d==3)
                        cout<<'u';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    cout<<'u';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    d=1;
                }
                else if(d==1||d==0){
                    if(d==0)
                        cout<<'c';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    cout<<'c';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    d=2;
                }
            }    
            
            else if(heng==0&&shu>0){//正上
                if(d==1)
                    cout<<'u';
                else if(d==2)
                    cout<<'c'<<'c';
                else if(d==3)
                    cout<<'c';
                    
                for(int i=1;i<=shu;i++) 
                    cout<<'f';
                d=0;
            }
            
            else if(heng==0&&shu<0){//正下
                if(d==1)
                    cout<<'c';
                else if(d==0)
                    cout<<'c'<<'c';
                else if(d==3)
                    cout<<'u';
                
                shu=-shu;
                for(int i=1;i<=shu;i++)
                    cout<<'f';
                d=2;
            }
            
            
            else if(heng<0&&shu>0){//左上
                heng=-heng;
                if(d==1||d==0){
                    if(d==1)
                        cout<<'u';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    cout<<'u';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    d=3;
                } 
                else if(d==3||d==2){
                    if(d==2)
                        cout<<'c';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    cout<<'c';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    d=0;
                }
            } 
            
            else if(heng<0&&shu<0){//左下
                heng=-heng,shu=-shu;
                if(d==0||d==3){
                    if(d==0)
                        cout<<'u';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    cout<<'u';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    d=2;
                } 
                else if(d==1||d==2){
                    if(d==1)
                        cout<<'c';
                    for(int i=1;i<=shu;i++)
                        cout<<'f';
                    cout<<'c';
                    for(int i=1;i<=heng;i++)
                        cout<<'f';
                    d=3;
                }
            }
            
            else if(shu==0&&heng<0){//正左 
                heng=-heng;
                if(d==1)
                    cout<<'c'<<'c';
                else if(d==2)
                    cout<<'c';
                else if(d==0)
                    cout<<'u';
                for(int i=1;i<=heng;i++)
                    cout<<'f';
                d=3;
            }
            
            else if(shu==0&&heng>0){//正右 
                if(d==0)
                    cout<<'c';
                else if(d==2)
                    cout<<'u';
                else if(d==3)
                    cout<<'c'<<'c';
                
                for(int i=1;i<=heng;i++)
                    cout<<'f';
                d=1;
            }
            
            
            else if(heng==0&&shu==0)
                continue;
                
            
        }
        cout<<endl;
        
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值