【BFS】翻币问题

题目

有N个硬币(6<=N<=20000)全部正面朝上排成一排,每次将其中5个硬币翻过来放在原位置,直到最后全部硬币翻成反面朝上为止。试编程找出步数最少的翻法,输出最少步数及翻法。

输入

从键盘输入一个正整数N(6<=N<=20000),表示硬币的数量。

输出

第1行:一个整数,表示最少步数

思路

分析:本题的关键是找出从当前状态如何变化到下一状态(即变化的规律)。
任意翻转5个硬币,正反面的个数变化为:
5正0反 正-5 反+5
4正1反 正-3 反+3
3正2反 正-1 反+1
2正3反 正+1 反-1
1正4反 正+3 反-3
0 正5反 正+5 反-5

代码

#include<cstdio>
#include<cmath>
int s=0,n,k,h,t,z[1001]={0},fj[1001]={0};
bool a[1001];
int fz[7]={0,-5,-3,-1,1,3,5},ff[7]={0,5,3,1,-1,-3,-5};
void bfs(){
    h=0;t=1;
    z[1]=n;
    fj[1]=0; //这个存步数
    do{
        h++;
        for(k=1;k<=6;k++) //6种变化方式
          if(z[h]>=6-k&&n-z[h]>=k-1){ //符合条件
              t++;
              z[t]=z[h]+fz[k];  //存入状态
              fj[t]=fj[h]+1;
              if (a[z[t]]==false) a[z[t]]=1; //有木有被搜过
              else t--;
              if(z[t]==0){ //符合条件
                printf("%d",fj[t]);
                return;
              }
          }
    }
    while(h<t);
}
int main(){
    scanf("%d",&n);
    bfs();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值