• 蓝桥杯 6翻硬币


    问题描述

    小明正在玩一个“翻硬币”的游戏。

    桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。

    比如,可能情形是:**oo***oooo

    如果同时翻转左边的两个硬币,则变为:oooo***oooo

    现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

    我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:

    输入格式

    两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000

    输出格式

    一个整数,表示最小操作步数。

    样例输入1
    **********
    o****o****
    样例输出1
    5
    样例输入2
    *o**o***o***
    *o***o**o***
    样例输出2
    1
    题目标签给的贪心..感觉不是很恰当。这题乍一看可能没啥头绪,但是仔细一想,借用大佬总结的一句话:

    “很容易证明,一个字符串如果可以通过翻转相邻两个的字符变成另一个字符串,则这两个字符串必定有偶数(包括0)个字符不同”。

    题目没说“相邻”是左邻还是右邻,不妨从字符串的左往右遍历反转,这样能保证只考虑一边。一个硬币只能有两种状态,设现在处理到了第i个硬币,当它和目标硬币一样时无需反转;当不一样时,把它翻转后再将第i+1个硬币反转,之后进行下一步判断。
    #include <bits/stdc++.h>
    using namespace std;
    char s[1005];
    char ss[1005];
    int main()
    {
        scanf("%s",s);
        scanf("%s",ss);
        int i,j;
        int cnt=0; 
        for(i=0;i<strlen(s);i++)
        {
            if(s[i]==ss[i])continue;
            if(i==strlen(s)-1)
            {
                cnt=1;
            }
            s[i]=ss[i];
            s[i+1]=s[i+1]=='*'?'o':'*';
            cnt++;
        }
        cout<<cnt;
        return 0;
    }
  • 相关阅读:
    数据结构总结——线段树
    [bzoj2131]免费的馅饼 树状数组优化dp
    [机房练习赛7.26] YYR字符串
    博客已搬家
    AFO
    COGS-2551 新型武器
    UVALive-3716 DNA Regions
    UVALive-4850 Installations
    UVALive-3983 Robotruck
    UVA-10859 Placing Lampposts
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/12358335.html
Copyright © 2020-2023  润新知