题目
有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();
}