紫书第三章课后习题--UVa455

本文介绍了解决UVa455问题的一种方法,通过枚举字符串长度并验证其是否构成循环节来找到最短的重复模式。利用字符串长度与循环节长度的关系简化了搜索过程。

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

题目:UVa455


地址:https://vjudge.net/problem/UVA-455

题解:

一开始,本能考虑直接求解循环周期,结果发现会出现各种各样的问题。

而后看了其他人的解答,说是可以暴力。

再一看数据范围,发现字符串的长度,最大也仅仅只有80,所以答案也就是这80个数中的一个,那么完全可以直接暴力枚举可能的长度,然后对于每一个可能的长度进行判断验证,看是否为循环节,又由于若有多个循环节,取最小的那一个,所以采取从1开始枚举,只要找出一个就可以停止枚举,直接输出。

还有就是,可以根据循环节与字符串的长度之间的关系,可以跳过对一些长度的判断,因为字符串的长度len一定是循环节k的整数倍。

编程技巧:

①代码:for(int j =0;j < len;++j)           ///验证字符串是否是按i进行循环

    if(s[j%i] != s[j])

       break;

    解释:s[j%i]始终是s中0~i-1的字符,依次与s中所有字符进行匹配,验证是否按此进行循环。

 

 

AC代码:

#include<bits/stdc++.h>

using namespace std;

 

int T;

string s;

 

int main(){

    cin >> T;

    while(T--){

        s.clear();

        cin >> s;

        int len = s.length();

        int ans = -1;

        for(int i = 1;i <= len;++i){           ///枚举循环节的长度

            if(len%i)   continue;              ///如果i不是len的因子,那么肯定不是循环节长度

            int flag = 1;

            for(int j = 0;j < len;++j)         ///验证字符串是否是按i进行循环

                if(s[j%i] != s[j]){

                    flag = 0;

                    break;

                }

            if(!flag)   continue;

            ans = i;

            break;

        }

        cout << ans << endl;

        if(T)  cout << endl;

    }

    return 0;

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值