HDU5920(字符串模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5920

题意:将一个数字分成不超过50个回文数字,只要不超过50个就行,不一定要最小。

思路:一道算是比较简单的题被我越搞越复杂。从中间开始向两边遍历并逐位赋值给b,找到不对称的地方时取较小的数,每次找到的b都是小于a的较大回文数字。如a = 123345,则第一个回文数字b = 123321; a = 12223 , b = 12221,;a = 32221,b = 12221,具体见注释吧。

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
char a[N],b[N],c[N],ans[N][N];
int main()
{
    int T,cas = 1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",a);
        int num = 0,len = strlen(a);
        while(len >= 1)
        {
            //获取回文数字b
            int flag = 0;
            b[len >> 1] = a[len >> 1];
            for(int i = len / 2 - 1; i >= 0; i--)
            {
                if(a[i] != a[len - 1 - i] && !flag)//第一次找到不对称的地方
                {
                    flag = 1;
                    b[i] = b[len - 1 - i] = min(a[i],a[len - 1 - i]);
                }
                else
                    b[i] = b[len - 1 - i] = a[i];
            }
            b[len] = 0;

            //特判
            if(!flag)//a已经是回文串
            {
                strcpy(ans[num++],a);
                break;
            }
            if(b[0] == '0')//特判
            {
                if(a[0] == '1')//分成1和999999.....
                {
                    b[0] = '1',b[1] = 0;
                    strcpy(ans[num++],b);
                    for(int i = 0; i < len - 1; i++)
                        b[i] = '9';
                    b[len - 1] = 0;
                    strcpy(ans[num++],b);
                }
                else//分成9+199..991,8 + 299..992,7 + 399..993等
                {
                    b[0] = b[len - 1] = (char)(a[0] - 1);
                    for(int i = 1; i < len - 1; i++)
                        b[i] = '9';
                    b[len] = 0;
                    strcpy(ans[num++],b);
                    int t6 = 11 - (int)(a[0] - '0');
                    b[0] = (char)(t6 + '0');
                    b[1] = 0;
                    strcpy(ans[num++],b);
                }
                if((len & 1) && (a[len >> 1] != '0'))//奇数位中间位置可能不为0,需要再次计算
                {
                    strcpy(a,a + len/2);
                    len = (len + 1) >> 1;
                    continue;
                }
                break;
            }

            // 获取c,c = a - b
            int t4 = 0;
            for(int i = len - 1; i >= 0; i--)
            {
                int t1 = a[i] - '0', t2 = b[i] - '0';
                int t3 = (t1 - t2 - t4 + 10) % 10;
                c[i] = (char)(t3 + '0');
                t4 = (int)((a[i] - b[i] - t4) < 0);
            }
            c[len] = 0;

            //清除c的前导零
            int t5;
            for(int i = 0; i < len; i++)
            {
                if(c[i] != '0')
                {
                    t5 = i;
                    break;
                }
            }

            strcpy(ans[num++],b);
            strcpy(a,c + t5);//将c赋值给a继续下一次循环
            len = strlen(a);
        }
        printf("Case #%d:\n",cas++);
        printf("%d\n",num);
        for(int i = 0; i < num; i++)
            printf("%s\n",ans[i]);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
字符串哈希滑动窗口是一种用于处理字符串的算法。它主要用于在给定的字符串中找到满足特定条件的子串。 在字符串哈希滑动窗口算法中,我们首先计算原始字符串的哈希值。然后,我们使用一个滑动窗口来遍历字符串,每次滑动一个固定长度的窗口。我们可以通过比较每个窗口内的子串的哈希值来判断是否满足条件。 具体而言,我们可以使用BKDRHash等哈希函数来计算字符串的哈希值。然后,我们枚举每个可能的起点,并使用滑动窗口来计算窗口内的子串的哈希值。通过比较窗口内的子串的哈希值,我们可以判断是否满足条件。 对于滑动窗口的移动,如果窗口内的子串满足条件,我们可以继续将窗口往右移动一个固定的长度。如果窗口内的子串不满足条件,我们将窗口的右边界移到最右端,并依次比较新窗口内的子串的哈希值。 综上所述,字符串哈希滑动窗口算法是通过计算字符串的哈希值,并使用滑动窗口来遍历字符串,以找到满足特定条件的子串。这个算法可以高效地处理字符串,并且能够应用于各种字符串相关的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [String (字符串哈希+滑动窗口)](https://blog.csdn.net/weixin_43872264/article/details/107571742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【字符串hash+滑动窗口】String HDU - 4821](https://blog.csdn.net/qq_45599865/article/details/111143633)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值