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. 如果这个字符串从后往前从前往后看是一样的即说明该串可能通过魔镜复制出来,所以只需要对该串的一半再次进行判断即可,直到不为回文串时,
该字符串长度即为最初可能的最小长度
1674

被折叠的 条评论
为什么被折叠?



