zoukankan      html  css  js  c++  java
  • 洛谷P2799 国王的墨镜 题解 递归

    题目链接:洛谷P2799

    题目描述

    国王有一个魔镜,可以把任何接触镜面的东西变成原来的两倍——只是,因为是镜子嘛,增加的那部分是反的。比如一条项链,我们用AB来表示,不同的字母表示不同颜色的珍珠。如果把B端接触镜面的话,魔镜会把这条项链变为ABBA。如果再用一端接触的话,则会变成ABBAABBA(假定国王只用项链的某一端接触魔镜)。给定最终的项链,请编写程序输出国王没使用魔镜之前,最初的项链可能的最小长度。

    输入格式

    只有一个字符串,由大写英文字母组成(字母数<=100000),表示最终的项链。

    输出格式

    只有一个整数,表示国王没使用魔镜前,最初的项链可能的最小长度。

    样例输入

    ABBAABBA
    

    样例输出

    2
    

    题目分析

    本题涉及算法:递归。
    首先你思考一下,如果给你一个长度为 (n) 的字符串 (s),你需要判断它是否是轴对称,并且还不能是奇数的:

    • 如果 (n) 为奇数,那么 (n) 就是最小长度(因为奇数无法作为镜子的两边进行映射),直接返回 (n) 就是最小长度;
    • 然后考虑一下 (n) 为偶数的情况,这种情况下我们需要从 (s[0]) 遍历到 (s[n/2-1]) 遍历 (s[i]) ,比较 (s[i])(s[n-1-i]) ,如果 (s[i] != s[n-1-i]) ,说明它不是轴对称的,直接返回 (n) 就是最小长度。

    如果 (n) 为偶数并且 (s[0..n-1]) 是轴对称的,那么我们继续去判断 (s[0..n-1]) 的前 (n/2) 个元素组成的子串;
    如果 (n/2) 为偶数并且 (s[0..frac{n}{2}-1]) 是轴对称的,那么我们继续去判断 (s[0..frac{n}{2}-1]) 的前 (n/4) 个元素组成的子串;
    ……
    如是循环,直到我们找到一个 (n) 为奇数或者它不是轴对称的。这个时候对应的 (n) 就是我们想要的最小的长度。
    我们可以开一个函数 int check(string s, int n) ,它用于判断字符串 (s) 的前 (n) 的最小长度,
    如果 (n) 是奇数 或者 (s) 不是轴对称的,该函数直接返回 (n) ,说明 (n) 就是它的最小程度;
    否则,它是偶数长度并且是轴对称的,那么它返回的结果就是 check(s, n/2) 的值。
    按这种方法进行递归,最终能找到我们想要的答案。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    // check函数用于返回s的前n个字符能够组成的最小长度
    int check(string s, int n) {
        if (n % 2) return n; // n为奇数时,直接返回n
        for (int i = 0; i < n/2; i ++)
            if (s[i] != s[n-1-i])   // s不轴对称,直接返回n
                return n;
        return check(s, n/2);   // 递归进s的前n/2个字符进行判断
    }
    string s;
    int n;
    int main() {
        cin >> s;
        n = s.length();
        cout << check(s, n) << endl;
        return 0;
    }
    
  • 相关阅读:
    everything is nothing
    基础算法
    OC 优化目录
    iOS 更改启动视图
    单例--iOS
    OC-Objection 学习笔记之一:简单的开始
    iOS 类库列表
    IOS 上线问题
    OC强弱引用的使用规则
    设置桌面图标
  • 原文地址:https://www.cnblogs.com/quanjun/p/12208863.html
Copyright © 2011-2022 走看看