LightOJ 1396 Palindromic Numbers (III)(贪心)

Description
Vinci is a little boy and is very creative. One day his teacher asked him to write all the Palindromic numbers from 1 to 1000. He became very frustrated because there is nothing creative in the task. Observing his expression, the teacher replied, “All right then, you want hard stuff, you got it.” Then he asks Vinci to write a palindromic number which is greater than the given number. A number is called palindromic when its digits are same from both sides. For example: 1223221, 121, 232 are palindromic numbers but 122, 211, 332 are not. As there can be multiple solutions, Vinci has to find the number which is as small as possible.

Input
Input starts with an integer T (≤ 30), denoting the number of test cases.

Each case starts with a line containing a positive integer. This integer can be huge and can contain up to 105 digits.

Output
For each case, print the case number and the minimum possible palindromic number which is greater than the given number.

Sample Input
5
121
1
1332331
11
1121
Sample Output
Case 1: 131
Case 2: 2
Case 3: 1333331
Case 4: 22
Case 5: 1221

我想说。。这是一道令人难过的。。。模拟题。。。
要使数字串成为比原串大的回文串,并且这个数字要尽量的小。
1)如果它已经是一个回文串了,因为要尽量小,我们肯定是要最中心的数字变大。
2)如果它不是一个回文串,那我们肯定要进行修改,先把它改成一个尽量小回文串(修改后半段数),再考虑这个回文串与原串的大小关系。回到1)。
实现:
我是用递归,solve(0,n-1),从两头向中间修改。其中需要用一个全局变量来记录之前的改变使得当前串变大还是变小了。如果是变小了,那么最中心的数字必须变大,如果变大了,最中心的数字可以不变。
细节:如果是299992 这种数,就要变成300003.
如果是9999 这种,变成10001,需要特殊输出。
一把辛酸泪TUT!!!!!
细节决定成败。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define mem(array) memset(array,0,sizeof(0))
int t,n,ans,da;
char a[100005],s[100005];
int solve(int l,int r)
{
    if(l==r) 
    {
        if(da==0) 
        { 
            s[r]++;
            if(s[r]>'9') 
                {
                    s[r]='0';
                    return 1;
                }
        }
        return 0;
    }
    if(s[l]>s[r]) da=1;
    if(s[l]<s[r]) da=0;
    s[r]=s[l];
    if(l+1==r){
        if(da) return 0;
        else {
            s[l]++;
            s[r]++;
            if(s[l]>'9') {  
                s[l]='0';
                s[r]='0';
                return 1;
            }
            else return 0;
        }
    }
    if(solve(l+1,r-1)) {
        s[l]++;
        s[r]++;
        if(s[l]>'9') {
            s[l]='0';
            s[r]='0';
            return 1;
        }
    }
    return 0;
}
int spp()
{
    cout<<1;
    for(int i=0;i<n-1;i++)
        cout<<s[i];
    cout<<1<<endl;
    return 0;
}
int main()
{
    freopen("in.txt","r",stdin);
    scanf("%d\n",&t);
    for(int k=1;k<=t;k++)
    {
        gets(s);
        n=strlen(s);
        da=0;
        int x=solve(0,n-1);
        printf("Case %d: ",k );

        if(x) spp();
        else 
        {
            for(int i=0;i<n;i++) cout<<s[i];
            cout<<endl;
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值