7-274 魔镜

7-274 魔镜

传说魔镜可以把任何接触镜面的东西变成原来的两倍,不过增加的那部分是反的。例如,对于字符串XY,若把Y端接触镜面,则魔镜会把这个字符串变为XYYX;若再用X端接触镜面,则会变成XYYXXYYX。对于一个最终得到的字符串(可能未接触魔镜),请输出没使用魔镜之前,该字符串最初可能的最小长度。

输入格式:

测试数据有多组,处理到文件尾。每组测试输入一个字符串(长度小于100,且由大写英文字母构成)。

输出格式:

对于每组测试数据,在一行上输出一个整数,表示没使用魔镜前,最初字符串可能的最小长度。

输入样例:

XYYXXYYX
XYXX

输出样例:

2
4

递归版本

#include <stdio.h>
// 7-274 魔镜
// https://pintia.cn/problem-sets/1468230055468535808/exam/problems/1468232170028072970
int main()
{
    char ch[100];//字符数组,保存输入的一行数据
    int ch_length=0;//字符数组的有效长度
    char c=99;
    while(c!=EOF)
    {
        c=getchar();
        if(c=='\n')
        {
            //开始判断,输入数组和数组长度
            int n=magic_test(ch,ch_length);
            printf("%d\n",n);
            ch_length=0;//字符数组长度清空
        }
        else
        {
            ch[ch_length]=c;//保存到字符数组中
            ch_length++;//长度加1
        }
    }
 
    //模拟的测试用例最后一行数据末尾带了换行,因此不需要下边的代码
    //提交使用的测试用例最后一行数据末尾没有换行,直接是EOF,因此需要下边代码
    //开始判断
    int n=magic_test(ch,ch_length-1);
    printf("%d",n);
    //多余代码结束
    return 0;
}
//判断一个字符串是否对称,不对称就返回字符串长度,对称就把数组折半继续判断
int magic_test(char ch[],int ch_length)//输入字符数组和长度
{
    //字符串长度为奇数,不对称,直接返回长度
    if(ch_length%2!=0)  {return ch_length;}
    //两个指针指向首尾,用来判断字符串是否对称
    char *p1=&ch[0],*p2=&ch[ch_length-1];
    //判断对称
    int i_i=1;//布尔值,1代表对称,0代表不对称
    for(int i=1;i<=ch_length/2;i++)//循环(长度/2)次就可以完成
    {
        if(*p1==*p2)//左右两个部分相等,说明这部分对称
        {
            p1++;p2--;
        }
        else{i_i=0;break;}//不对称就退出
    }
    if(i_i==1)//对称,数组折半,就继续调用自己,直到不对称时时返回长度
    {
        return magic_test(ch,ch_length/2);
    }
    else//不对称,返回字符串长度
    {
        return ch_length;
    }
}

循环版本

#include <stdio.h>
#include <string.h>

int main() {

    char str[100];
    while (scanf("%s", str) != EOF) {
        // flag表示当前字符串是否继续折半往下判断
        int flag = 1;
        // 表示目前最小长度
        int length = (int) strlen(str);
        // 首先判断长度是否为奇数,如果为奇数则不是回文串直接输出长度后继续下次循环
        if (length % 2 == 1) {
            printf("%d\n", length);
            continue;
        }
        // 判断是否为回文串,是则折半判断,否则返回长度
        while (length != 1 && flag) {
            // 开始判断
            for (int i = 0; i < length; ++i) {
                if (str[i] != str[length - i - 1]) {
                    printf("%d\n", length);
                    flag = 0;
                    break;
                }
            }
            if (flag) {
                length /= 2;
            }
            if(length == 1){
                printf("1\n");
            }
        }
    }

    return 0;
}

思路

- 首先特别感谢郑老师提供的思路和递归版本,让我又对递归进行了熟悉,又知道本题的解题思路,醍醐灌顶,我自己又写了一个循环版本供大家参考

1. 说一下我对题目的理解,如果一个字符串是奇数则该数不可能由另一个串通过镜面变成两倍得到,因为镜面复制出来的串永远是偶数个,所以该串的
   长度一定为最初可能的最小长度

2. 如果这个字符串从后往前从前往后看是一样的即说明该串可能通过魔镜复制出来,所以只需要对该串的一半再次进行判断即可,直到不为回文串时,
   该字符串长度即为最初可能的最小长度
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Likf(❁´◡`❁)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值