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

Posted stupid_one

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}
View Code

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

以上是关于HDU - 5920 Ugly Problem 求解第一个小于n的回文数的主要内容,如果未能解决你的问题,请参考以下文章

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

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

高精度 JAVAHDU 5920 Ugly Problem

POJ 3923 &amp; HDU 2487 Ugly Windows(模拟)

Ugly Problem

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