题目描述:将一列碗翻成口朝上,一把下去可能同时反转3个或2个(首尾),求最小翻转次数
题解:1.非常简单的枚举结果。可以过。
2.其实,很明显只需枚举是否反转第一个碗即可,其他的碗可以一步一步推导。
参考程序:
#include<stdio.h>
int num[21],step,flag;
int range()
{
int i;
for(i=0;i<20;i++)
if(num[i]==1)
return 0;
return 1;
}
void turn(int i)
{
num[i]=!num[i];
if(i>0)
num[i-1]=!num[i-1];
if(i<19)num[i+1]=!num[i+1];
}
void DFS(int i,int dp)
{
if(step==dp){
flag=range();
return;
}
if(i>=20||flag)return;
turn(i);
DFS(i+1,dp+1);
turn(i);
DFS(i+1,dp);
}
int main()
{
int i;
for(i=0;i<20;i++)
scanf("%d",&num[i]);
for(step=0;step<20;step++)
{
flag=0;
DFS(0,0);
if(flag)break;
}
printf("%d\n",step);
return 0;
}
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cmath>
using namespace std;
int bowl[25];
int bowl2[25];
int main(){
while (scanf("%d", &bowl[0]) != EOF){
bowl2[0] = bowl[0];
for (int i = 1; i < 20; i++){
scanf("%d", &bowl[i]);
bowl2[i] = bowl[i];
}
int flip_count = 0;
//not flip position 0
for (int i = 1; i < 20; i++){
if (bowl[i - 1]){
flip_count++;
bowl[i - 1] = 0;
bowl[i] = 1 - bowl[i];
bowl[i + 1] = 1 - bowl[i + 1];
}
}
int min_flip = flip_count;
if (bowl[19] == 1){
min_flip = 10000;
}
//flip bowl 0
flip_count = 1;
bowl2[0] = 1 - bowl2[0];
bowl2[1] = 1 - bowl2[1];
for (int i = 1; i < 20; i++){
if (bowl2[i - 1]){
flip_count++;
bowl2[i - 1] = 0;
bowl2[i] = 1 - bowl2[i];
bowl2[i + 1] = 1 - bowl2[i + 1];
}
}
if (bowl2[19] == 0){
min_flip = min_flip < flip_count ? min_flip : flip_count;
}
printf("%d\n", min_flip);
}
return 0;
}