HDU 5920 Ugly Problem (大数模拟 构造回文串)

18 篇文章 0 订阅
1 篇文章 0 订阅

大体题意:

给你一个长度不超过1000的大数,划分成n 个回文串,使得回文串的个数不超过50,并且回文串的和是这个大数!

思路:

大数模拟!

最长长度为1000    个数不超过50,显然必须是log级别的,也就是接近折半的运算!

所以我们先根据这个大数的前一半算出这个回文串是多少来,如果这个回文串小于当前的大数,直接减,在继续递归寻找!

如果大于当前大数, 你就必须找到一个非常接近它的回文串,其实也很好想,找到前一半,让前一半减1,这样在构造出的回文串一定小于当前大数,在继续递归即可!

比如说34567  直接构造34543 递归即可!

如果是 34511  构造出来34543  不能继续减,就让345减1,得344,构造出来的是34443 可以继续减,并且接近折半运算!

教训:

这种恶心的题目应对起来 可以写几个debug函数 看看哪里错了,这样更容易查错!

详细见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;
const int maxn = 2000 + 1;
vector<string>sans;
int cmpe(string s1,string s2){  // s1 > s2 = 1  s1 = s2 = 0 s1 < s2 = -1
    int len1= s1.length();
    int len2= s2.length();
    if (len1 > len2) return 1;
    else if (len1 < len2) return -1;
    else {
        if (s1 > s2) return 1;
        else if (s1 < s2) return -1;
        return 0;
    }
}
bool judge(string s){
    int len = s.length();
    for (int i = 0; i < (len+1)/2; ++i){
        if (s[i] != s[len-i-1])return false;
    }
    return true;
}
/**
1111111111111111110
 998877665544332211
01122334455667789/9
**/
string Mul(string s1,string s2){
    int len1 = s1.length();
    int len2 = s2.length();
    string ans = "";
    int tmp = len1-len2;
    int flag = 0;
    for (int i = len2-1; ~i; --i){
        if (s1[i+tmp]-flag >= s2[i]){
            ans = char(s1[i+tmp] - s2[i] - flag + 48) + ans;
            flag = 0;
        }
        else{
            ans = char(s1[i+tmp] + 10 - s2[i] - flag + 48) + ans;
            flag = 1;
        }
    }
    for (int i = tmp-1; ~i; --i){
        if (s1[i] - 48 - flag >= 0) ans = char(s1[i] - flag) + ans,flag = 0;
        else ans = char(s1[i] - flag + 10) + ans,flag = 1;
    }
    int p = 0;
    int anslen = ans.length();
    while(p < anslen && ans[p] == 48)++p;
    if (p != 0){
        if (p == anslen){
            ans[0] = 48;
            ans[1] = 0;
            ans.resize(1);
            return ans;
        }
        for (int i = 0; i < anslen - p; ++i){
            ans[i] = ans[i+p];
        }
        ans.resize(anslen-p);
    }
    return ans;
}
string unit = "1";
void deal(string s){
    if (judge(s)){
        sans.push_back(s);
        return;
    }
    int len = s.length();
    string t1;
    t1.resize(len);
    for(int i = 0; i < ((len&1)?len/2+1:len/2); ++i){
        t1[i] = t1[len-i-1] = s[i];
    }
    string t2;
    if (cmpe(s,t1) != -1){
        sans.push_back(t1);
        t2 = Mul(s,t1);
        deal(t2);
    }
    else {
        bool ok = 0;
        for (int i = 1; i < len-1; ++i) if (t1[i] != '0'){
            ok = 1;
            break;
        }
        if (!ok && t1[0] == t1[len-1] && t1[0] == 49){
            string zha = "1";
            sans.push_back(zha);
            zha = "";
//            puts("1");
            for (int i = 1; i < len; ++i) zha += "9";
            sans.push_back(zha);
            return;
        }

        t1.resize(len+1>>1);
        t2 = Mul(t1,unit);
        t2.resize(len);
        for (int i = 0; i < len/2; ++i){
            t2[len-i-1] = t2[i];
        }
        sans.push_back(t2);
        t1 = Mul(s,t2);
        deal(t1);
    }

}
char s[maxn];
void print(vector<string>& aa){
    printf("%d\n",aa.size());
    for (int i = 0; i < aa.size(); ++i)printf("%s\n",aa[i].c_str());
}
int main(){
//    debug();
    int T,ks = 0;
    scanf("%d",&T);
    while(T--){
        sans.clear();
        scanf("%s",s);
        printf("Case #%d:\n",++ks);
        deal(s);
        print(sans);
    }
    return 0;
}

Ugly Problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 898    Accepted Submission(s): 311
Special Judge


Problem Description
Everyone hates ugly problems.

You are given a positive integer. You must represent that number by sum of palindromic numbers.

A palindromic number is a positive integer such that if you write out that integer as a string in decimal without leading zeros, the string is an palindrome. For example, 1 is a palindromic number and 10 is not.
 

Input
In the first line of input, there is an integer T denoting the number of test cases.

For each test case, there is only one line describing the given integer s ( 1s101000 ).
 

Output
For each test case, output “Case #x:” on the first line where x is the number of that test case starting from 1. Then output the number of palindromic numbers you used, n, on one line. n must be no more than 50. en output n lines, each containing one of your palindromic numbers. Their sum must be exactly s.
 

Sample Input
  
  
2 18 1000000000000
 

Sample Output
  
  
Case #1: 2 9 9 Case #2: 2 999999999999 1
Hint
9 + 9 = 18 999999999999 + 1 = 1000000000000
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:   5932  5931  5930  5929  5928 
 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值