5.3二维数组->较难(蜂窝图)

问题描述 :

在一张由无限多个大小相等的正六边形无缝拼接的无限大的地图上,所有的正六边形都有一个唯一的编号,从1开始,一圈圈往外绕。下图中我画到第30个,但其实有无穷多个,下图中空白的区域的编号我还没画,但是每个正六边形都有一个唯一的编号。
在这里插入图片描述
你的任务是找到绕圈的规律并补完这张图上的空白的正六边形的数字,并且写个程序回答我,如果你从其中一个正六边形走到另一个正六边形,最少需要走几步。这里一“步”指的是从一个正六边形走到相邻的正六边形。所谓相邻,指的是两个正六边形有公共边。

输入说明 :

多组测试数据,最多会有5000组测试数据,所以请注意运行时间不要超时。

每组数据只有一行,包含两个整数n,m(1≤n,m≤1000)。

输出说明 :

对于每组测试数据,输出一行。一行当中只有一个数字,表示从编号n的正六边形走到编号m的正六边形所对应的最小步数。

解题思路:

其实相对于矩阵的运动,蜂窝状的图主要的难点有两个:
1、如何记录蜂窝点的坐标
———用函数来控制六个方向运动的坐标变化
2、如何通过蜂窝图上一个点坐标计算两者之间的距离
———水平垂直坐标差分别进行处理

所以这没有任何的技术含量,很对
就是一个大模拟。
但是模拟就一定要注意考虑周全,避免被卡数据。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
struct note{
    int x,y;
}dp[2000];
int x,y;
void change(int t)
{
    if(t==1)
        x-=2;
    if(t==2)
        x--,y++;
    if(t==3)
        x++,y++;
    if(t==4)
        x+=2;
    if(t==5)
        x++,y--;
    if(t==6)
        x--,y--;
    return ;
}
int main()
{
    int n;
    int i,j,k;
    int a,b;
    int t=8,p=6;
    dp[1].x=0;
    dp[1].y=0;
    //========
    dp[2].x=2;
    dp[2].y=0;
    //========
    dp[3].x=1;
    dp[3].y=1;
    //========
    dp[4].x=-1;
    dp[4].y=1;
    //========
    dp[5].x=-2;
    dp[5].y=0;
    //========
    dp[6].x=-1;
    dp[6].y=-1;
    //========
    dp[7].x=1;
    dp[7].y=-1;
    //========
    x=1,y=-1;
    int lp=1;
    for(t=8;t<=1201;)
    {
        ///change(way-fangxiang);
        ///if()///转完一圈
        {
            change(4);
            dp[t].x=x;
            dp[t++].y=y;
            ///lp为填充长度
            lp++;
        }
        int ksp;
        ksp=lp-1;
        while(ksp--)///3hao
        {
            change(3);
            dp[t].x=x;
            dp[t++].y=y;
        }
        ksp=lp;
        while(ksp--)///2hao
        {
            change(2);
            dp[t].x=x;
            dp[t++].y=y;
        }
        ksp=lp;
        while(ksp--)///1hao
        {
            change(1);
            dp[t].x=x;
            dp[t++].y=y;
        }
        ksp=lp;
        while(ksp--)///6hao
        {
            change(6);
            dp[t].x=x;
            dp[t++].y=y;
        }
        ksp=lp;
        while(ksp--)///5hao
        {
            change(5);
            dp[t].x=x;
            dp[t++].y=y;
        }
        ksp=lp;
        while(ksp--)///4hao
        {
            change(4);
            dp[t].x=x;
            dp[t++].y=y;
        }
    }
    //for(i=0;i<100l;i++)
    //    cout<<i<<" "<<dp[i].x<<" "<<dp[i].y<<endl;
    while(cin>>a>>b)
    {
       //cout<<dp[a].x<<" "<<dp[a].y<<endl;
        //cout<<dp[b].x<<" "<<dp[b].y<<endl;
        //cout<<min( abs(dp[a].x-dp[b].x) , abs(dp[a].y-dp[b].y) )<<endl;
        int cao,up,land;
        cao=abs(dp[a].x-dp[b].x);
        if(abs(dp[a].x-dp[b].x)%2==1)
            up=abs(dp[a].x-dp[b].x)/2+1;
        else
            up=abs(dp[a].x-dp[b].x)/2;
        land=abs(dp[a].y-dp[b].y);
        /*
        if(cao == land)
        {
            cout<<cao<<endl;
        }
        else if((land<=1 || up<=1))
        {
            cout<<max(up,land)<<endl;
        }
        if(land>1 && up>1 && cao!=land)
        {
            if(up==land)
                cout<<up+1<<endl;
            if(up>land)
            {
                cout<<up+1<<endl;
            }
            if(up<land)
                cout<<land+1<<endl;
        }
        */
            //cout<<abs(dp[a].y-dp[b].y)<<" "<<up<<" "<<abs(dp[a].y-dp[b].y)<<endl;
        //cout<<abs(dp[a].x-dp[b].x)+abs(dp[a].y-dp[b].y)<<endl;
        if(cao<=land)
            cout<<land<<endl;
        else
        {
            int hcl=cao-land;
            if(hcl%2==1)
                up=hcl/2+1;
            else
                up=hcl/2;
            cout<<up+land<<endl;
        }
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值