hdu 1195

 

题意:就是给你n组的四位数,在一次变化中又一位数字可以变化,而变化的方式为加一减一或者是与隔壁的互换,注意,是每一个数字都可以,

求最少的变化次数到达目标的数字

 

一看这个就应该知道这是一个bfs的题目,广搜么,不过要注意的就是标记,不然很有可能也出不来

我的代码写的比较繁琐,也比较糙,这个写的太复杂了,不过你也可以用循环来代替我的大部分代码,可以减少很多的书写量

 

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <queue>


using namespace std;
int ans;

queue<int >s;

bool mark[10005];
int step[10005];

int bfs(int x)
{
    int he,y,c[4];while(!s.empty()) s.pop();
    if(x==ans) return 0;
    s.push(x);
    mark[x]=false;
    while(!s.empty())
    {
        he=s.front();
        s.pop();    
        c[0]=he/1000;      //这个的目的就是判断每一位数字是否为9或者1,因为9加1就是1了,而1减1也会变成9,
        c[1]=(he-c[0]*1000)/100;
        c[2]=(he-c[0]*1000-c[1]*100)/10;
        c[3]=he%10;
        if(c[0]==9&&mark[he-8000]){s.push(he-8000);mark[he-8000]=false;step[he-8000]=step[he]+1;if(he-8000==ans){printf("%d\n",step[he-8000]);return 0;}}
        else if(mark[he+1000]&&c[0]!=9){s.push(he+1000);mark[he+1000]=false;step[he+1000]=step[he]+1;if(he+1000==ans){printf("%d\n",step[he+1000]);return 0;}}  //切记这里要加一个那位数不能为9或者1,否则可能出现3位数的情况
        if(c[1]==9&&mark[he-800]){s.push(he-800);mark[he-800]=false;step[he-800]=step[he]+1;if(he-800==ans){printf("%d\n",step[he-800]);return 0;}}
        else if(mark[he+100]&&c[1]!=9){s.push(he+100);mark[he+100]=false;step[he+100]=step[he]+1;if(he+100==ans){printf("%d\n",step[he+100]);return 0;}}
        if(c[2]==9&&mark[he-80]){s.push(he-80);mark[he-80]=false;step[he-80]=step[he]+1;if(he-80==ans){printf("%d\n",step[he-80]);return 0;}}
        else if(mark[he+10]&&c[2]!=9){s.push(he+10);mark[he+10]=false;step[he+10]=step[he]+1;if(he+10==ans){printf("%d\n",step[he+10]);return 0;}}
        if(c[3]==9&&mark[he-8]){s.push(he-8);mark[he-8]=false;step[he-8]=step[he]+1;if(he-8==ans){printf("%d\n",step[he-8]);return 0;}}
        else if(mark[he+1]&&c[3]!=9){s.push(he+1);mark[he+1]=false;step[he+1]=step[he]+1;if(he+1==ans){printf("%d\n",step[he+1]);return 0;}}
        if(c[0]==1&&mark[he+8000]){s.push(he+8000);mark[he+8000]=false;step[he+8000]=step[he]+1;if(he+8000==ans){printf("%d\n",step[he+8000]);return 0;}}
        else if(mark[he-1000]&&c[0]!=1){s.push(he-1000);mark[he-1000]=false;step[he-1000]=step[he]+1;if(he-1000==ans){printf("%d\n",step[he-1000]);return 0;}}
        if(c[1]==1&&mark[he+800]){s.push(he+800);mark[he+800]=false;step[he+800]=step[he]+1;if(he+800==ans){printf("%d\n",step[he+800]);return 0;}}
        else if(mark[he-100]&&c[1]!=1){s.push(he-100);mark[he-100]=false;step[he-100]=step[he]+1;if(he-100==ans){printf("%d\n",step[he-100]);return 0;}}
        if(c[2]==1&&mark[he+80]){s.push(he+80);mark[he+80]=false;step[he+80]=step[he]+1;if(he+80==ans){printf("%d\n",step[he+80]);return 0;}}
        else if(mark[he-10]&&c[2]!=1){s.push(he-10);mark[he-10]=false;step[he-10]=step[he]+1;if(he-10==ans){printf("%d\n",step[he-10]);return 0;}}
        if(c[3]==1&&mark[he+8]){s.push(he+8);mark[he+8]=false;step[he+8]=step[he]+1;if(he+8==ans){printf("%d\n",step[he+8]);return 0;}}
        else if(mark[he-1]&&c[3]!=1){s.push(he-1);mark[he-1]=false;step[he-1]=step[he]+1;if(he-1==ans){printf("%d\n",step[he-1]);return 0;}}
        y=c[1]*1000+c[0]*100+c[2]*10+c[3];   //这个就是与隔壁的交换,只有三种情况,就是每一个都与右边的交换。
        if(mark[y]){s.push(y);mark[y]=false;step[y]=step[he]+1;if(y==ans){printf("%d\n",step[y]);return 0;}}
        y=c[0]*1000+c[2]*100+c[1]*10+c[3];
        if(mark[y]){s.push(y);mark[y]=false;step[y]=step[he]+1;if(y==ans){printf("%d\n",step[y]);return 0;}}
        y=c[0]*1000+c[1]*100+c[3]*10+c[2];
        if(mark[y]){s.push(y);mark[y]=false;step[y]=step[he]+1;if(y==ans){printf("%d\n",step[y]);return 0;}}
        if(he==ans)
        {
            printf("%d\n",step[he]);
            return 0;
        }
    }
    return 0;
}

int main()
{
    int n,start;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&start,&ans);
        memset(mark,true,sizeof(mark));
        memset(step,0,sizeof(step));
        step[start]=0;
        bfs(start);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Tree-dream/p/5400840.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值