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

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

posted on 2017-08-20 19:59  stupid_one  阅读(273)  评论(0编辑  收藏  举报

导航