poj之旅——3185

本文探讨了一道关于碗翻转的算法题,旨在通过最少的步骤将所有碗口朝上。文章提供了两种不同的算法实现思路及对应的源代码,分别采用递归深度优先搜索和迭代方法解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:将一列碗翻成口朝上,一把下去可能同时反转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;

}




 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值