HDU - 5920 Ugly Problem 求解第一个小于n的回文数

http://acm.hdu.edu.cn/showproblem.php?pid=5920

http://www.cnblogs.com/xudong-bupt/p/4015226.html

把前半部分复制过去,如果太大,那么早到第一个会使得其太大的点,减1,然后对应的中间的变成9

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
#define X first
#define Y second
#define clr(u,v); memset(u,v,sizeof(u));
#define in() freopen("3.h","r",stdin);
#define out() freopen("ans","w",stdout);
#define Clear(Q); while (!Q.empty()) Q.pop();
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const ll INF = 1e17;
const int inf = 0x3f3f3f3f;
const int maxn = 1e3 + 20;
char nxt[maxn], str[maxn];
bool is(char str[], int lenstr) {
    int i = 1, j = lenstr;
    while (i < j) {
        if (str[i] != str[j]) return false;
        ++i;
        --j;
    }
    return true;
}
void bigCut(char str[], char sub[], char str3[]) {
    int lenstr = strlen(str + 1), lensub = strlen(sub + 1);
//    printf("%d\n", lenstr);
    for (int i = 1; i <= lenstr; ++i) str[i] -= ‘0‘;
    for (int i = 1; i <= lensub; ++i) sub[i] -= ‘0‘;
    int use = lenstr;
    for (int i = lensub; i >= 1; --i, --use) {
        if (str[use] < sub[i]) {
            str[use] = 10 + str[use] - sub[i];
            int p = use - 1;
            while (p >= 1 && !str[p]) {
                str[p] = 9;
                p--;
            }
            str[p]--;
        } else str[use] -= sub[i];
    }
    for (int i = 1; i <= lenstr; ++i) str[i] += ‘0‘;
    int to = 0;
    int p = 1;
    while (p < lenstr && str[p] == ‘0‘) p++;
    while (p <= lenstr) {
        str3[++to] = str[p++];
    }
    str3[++to] = ‘\0‘;
}
char s2[2222];
void findNxt(char str[], int lenstr) {
    if (is(str, lenstr)) {
        strcpy(nxt + 1, str + 1);
        return;
    }
    if (str[1] == ‘1‘) {
        bool flag = true;
        for (int i = 2; i <= lenstr; ++i) {
            if (str[i] != ‘0‘) {
                flag = false;
                break;
            }
        }
        if (flag) {
            for (int i = 1; i <= lenstr - 1; ++i) nxt[i] = ‘9‘;
            nxt[lenstr] = ‘\0‘;
            return;
        }
    }
    for (int i = 1,j=lenstr; i <=j; ++i,--j) {
        s2[j] = s2[i] = str[i];
    }
    for (int i = lenstr / 2 + 1; i <= lenstr; ++i) {
        if (str[i] < s2[i]) {
            for(int j=(lenstr+1)/2;;j--)
            {
                if(s2[j]==‘0‘)
                {
                    s2[j]=‘9‘;
                    s2[lenstr-j+1]=s2[j];
                }
                else
                {
                    s2[j]--;
                    s2[lenstr-j+1]=s2[j];
                    break;
                }
            }
            break;
        }
    }
    for (int i = 1; i <= lenstr; ++i) nxt[i] = s2[i];
    nxt[lenstr + 1] = ‘\0‘;
}

char res[2222];
char sub[222] = "01";
vector<string> vc;
int f;
void work() {
    printf("Case #%d:\n", ++f);
    vc.clear();
    scanf("%s", str + 1);
    int lenstr = strlen(str + 1);
//    findNxt(str, lenstr);
//    printf("%s\n", nxt + 1);
    while (true) {
        findNxt(str, lenstr);
        if (strcmp(str + 1, nxt + 1) == 0) {
            if (is(str, lenstr)) {
                vc.push_back(str + 1);
                break;
            } else {
                vc.push_back("1");
                sub[0] = ‘0‘;
                sub[1] = ‘1‘;
                sub[2] = ‘\0‘;
                bigCut(str, sub, res);
                strcpy(str + 1, res + 1);
                lenstr = strlen(str + 1);
                continue;
            }
        }
        vc.push_back(nxt + 1);
        bigCut(str, nxt, res);
        strcpy(str + 1, res + 1);
        lenstr = strlen(str + 1);
    }
    printf("%d\n", vc.size());
    for (int i = 0; i < vc.size(); ++i) {
        printf("%s\n", vc[i].c_str());
    }
}

int main()
{
    #ifdef LOCAL
    in();
    #else
    #endif
    int t;
    scanf("%d", &t);
    while (t--) work();
    return 0;
}

贪心的思路是:最好不要更改前半部分,权值大。

时间: 2024-10-18 01:45:58

HDU - 5920 Ugly Problem 求解第一个小于n的回文数的相关文章

HDU 5920 Ugly Problem 【模拟】 (2016中国大学生程序设计竞赛(长春))

Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0Special Judge Problem Description Everyone hates ugly problems. You are given a positive integer. You m

【高精度 JAVA】HDU 5920 Ugly Problem

题意 给你一个数字n(n < 10^1000),将其拆成若干个回文串(不超过50个)输出拆分方案 分析 不难想到,我们可以每次给n减一个小于他的最大的回文串,这样能够尽量构造出最少数量的回文串,方法可以使直接将前一半反转贴到后一半,如果比原来的数字大,那么前一半减少1,再反转贴为后一半 比较坑的地方就是 如果构造出来的是11比n大, 那么前一半-1变成了00 ,特判一下,应该为9:如果构造出来是101比n大,应该特判为99 这个题没太多好讲的,我想在这里记录一下java编程心得,以后也会更新 主

2016中国大学生程序设计竞赛(长春)-重现赛 1010Ugly Problem 回文数 模拟

Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0Special Judge Problem Description Everyone hates ugly problems. You are given a positive integer. You m

HDU 1282 回文数猜想(简单数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1282 Problem Description 一个正整数,如果从左向右读(称之为正序数)和从右向左读(称之为倒序数)是一样的,这样的数就叫回文数.任取一个正整数,如果不是回文数,将该数与他的倒序数相加,若其和不是回文数,则重复上述步骤,一直到获得回文数为止.例如:68变成154(68+86),再变成605(154+451),最后变成1111(605+506),而1111是回文数.于是有数学家提出一个

(HDU)1282 -- 回文数猜想

题目链接:http://vjudge.net/problem/HDU-1282 做这个题目的时候想了很多. 第一,怎么判断一个数是不是回文数(可以用int表示的时候): 最初的想法是用字符串处理,int(log10()+1)来得到位数...(服了自己)... 然后从两段向中间对比,全部满足就是回文数,后来觉得好麻烦啊. 后来写了个函数得出一个数的反过来的数字,要用的时候用个if语句判断. 第二,格式问题... 反正做这题的时候脑子有点懵,状态很一般,打不过水题. 1 #include <cstd

杭电 HDU ACM 1282 回文数猜想

回文数猜想 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4940    Accepted Submission(s): 2958 Problem Description 一个正整数,如果从左向右读(称之为正序数)和从右向左读(称之为倒序数)是一样的,这样的数就叫回文数.任取一个正整数,如果不是回文数,将该数与他的倒序数相加,若其和不

[亚马逊amazon] 在线笔试题 大于非负整数N的第一个回文数 Symmetric Number

1.题目 如标题,求大于整数N(N>=0)的第一个回文数的字符串表示形式. 这个题目也是当时笔试第一次见到,花了一个小时才做出了.慢慢总结还是挺简单的. 2.分析 分析如下: (1)一位数N(9除外). 第一个大于N回文数等于N+1,如大于3的第一个回文数是4. (2)奇数位(一位数除外) 需要看“左边反转数字”是否大于"右边数字". 1)如果小于等于,则“左边+中间字母”组成的数字+1,再对称就可以. 2)如果大于,则左边数字直接对称到右边就可以啦. (3)偶数位 需要看“左边

LeetCode Problem 9:Palindrome Number回文数

描述:Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of using extra space. You could a

大于非负整数N的第一个回文数 Symmetric Number

1.题目 如标题,求大于整数N(N>=0)的第一个回文数的字符串表示形式. 2.样例 1  --> 2 9  -->11 12345 -->12421 123456 -->124421 999 -->1001 3.分析 借用:http://www.cnblogs.com/xudong-bupt/p/4015226.html 4.代码 1 import java.util.Scanner; 2 3 4 public class SymmetricNumber { 5 6