说起这道题, 真是一把辛酸泪.

题意

将一个正整数 $n(\le 10^{1000})$ 分解成不超过50个回文数的和.

做法

构造.

队友UHC提出的一种构造方法, 写起来比较方便一些, 而且比较巧妙. 可惜我码力太弱, 现场没调出来.

大体的想法是:

将一个数"等"分成两半. 如果长度为奇数可以采取下面两种处理方法之一.

  1. 在开头补0.
  2. 后一半 (低位) 的长度向下取整.

我采取第2种处理方式.

设前一半的长度为$h_1$, 后一半的长度为 $h_2$.

然后将前一半长

(写不下去了..., 贴代码...)

Implementation

#include <bits/stdc++.h>
using namespace std; using num=vector<int>;
using iter=num::iterator;
using riter=num::reverse_iterator; bool Less(const num &a, const num &b){ // a and b are of same length
for(auto it1=a.rbegin(), it2=b.rbegin(); it1!=a.rend(); ++it1, ++it2)
if(*it1 != *it2){
return *it1 < *it2;
}
return false;
} void borrow(num &a){
for(int i=a.size()/2; i<a.size(); i++)
if(a[i]){
for(--a[i]; i; a[--i]+=9); //?
break;
}
while(a.size() && *a.rbegin()==0)
a.pop_back();
} void split(num &lo, num &hi, const num &a){
auto mid=a.begin()+a.size()/2;
lo={a.begin(), mid};
hi={mid, a.end()};
} num operator-(num a, num b){ // a and b are of same length && a >= b
num res;
for(int i=0; i<a.size(); i++){
if(a[i]<b[i]){
a[i]+=10;
a[i+1]-=1;
}
res.push_back(a[i]-b[i]);
} for(; res.size() && *res.rbegin()==0; )
res.pop_back(); if(res.size()){ //error-prone
for(int i=0; i<res.size()-1; i++){
res[i+1]+=res[i]/10;
res[i]%=10;
} for(; *res.rbegin()>9; ){
int t=*res.rbegin();
*res.rbegin()%=10;
res.push_back(t/10);
}
} for(auto x:res){
assert(x>=0 && x<10);
} return res;
} vector<num> res; void out(const num &a){
for(auto it=a.rbegin(); it!=a.rend(); ++it)
cout<<*it;
cout<<endl;
} void solve(num &a){
res.clear();
num lo, hi;
int ones=0; while(a.size()>1){
// out(a);
split(lo, hi, a);
num rhi(hi.rbegin(), hi.rbegin()+lo.size());
if(Less(lo, rhi)){
borrow(a);
++ones;
continue;
}
a=lo-rhi;
// There is no advantage to using {} initialization, and one trap,
// when using auto to get the type determined by the initializer.
// The trap is that if the initializer is a {}-list, we may not want its
// type deduced.
//initializer_list<num> xx={rhi};
//cout<<typeid(xx).name()<<endl;
auto tmp=rhi;
//cout<<typeid(tmp).name()<<endl;
for(auto &x: hi)
tmp.push_back(x);
res.push_back(tmp);
} if(a.size()) res.push_back(a); assert(res.size() + ones <= 50); printf("%d\n", res.size()+ones);
for(auto &x: res)
out(x);
while(ones--)
puts("1");
} char s[1<<10]; int main(){ // num x, y;
// in g++:
// direct-list-intialization of 'auto' requires exactly one element
// for deduction to 'std::initializer_list', use copy-list-intialization (i.e. add '=' before the '{')
// auto xx{x, y}; int T, cas=0;
num a;
for(cin>>T; T--; ){
scanf("%s", s);
a.clear();
int n=strlen(s);
for(int i=n-1; i>=0; --i)
a.push_back(s[i]-'0');
printf("Case #%d:\n", ++cas);
solve(a);
}
return 0;
}

HDU 5920 Ugly Problem的更多相关文章

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

    Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

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

    http://acm.hdu.edu.cn/showproblem.php?pid=5920 http://www.cnblogs.com/xudong-bupt/p/4015226.html 把前半 ...

  3. HDU 5920 Ugly Problem 高精度减法大模拟 ---2016CCPC长春区域现场赛

    题目链接 题意:给定一个很大的数,把他们分为数个回文数的和,分的个数不超过50个,输出个数并输出每个数,special judge. 题解:现场赛的时候很快想出来了思路,把这个数从中间分为两部分,当位 ...

  4. D - Ugly Problem HDU - 5920

    D - Ugly Problem HDU - 5920 Everyone hates ugly problems. You are given a positive integer. You must ...

  5. hdu-5920 Ugly Problem(贪心+高精度)

    题目链接: Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  6. HDU 3549 Flow Problem(最大流)

    HDU 3549 Flow Problem(最大流) Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...

  7. hdu 5106 Bits Problem(数位dp)

    题目链接:hdu 5106 Bits Problem 题目大意:给定n和r,要求算出[0,r)之间全部n-onebit数的和. 解题思路:数位dp,一个ct表示个数,dp表示和,然后就剩下普通的数位d ...

  8. Ugly Problem

    Ugly Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Spec ...

  9. HDU 3374 String Problem (KMP+最大最小表示)

    HDU 3374 String Problem (KMP+最大最小表示) String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory ...

随机推荐

  1. WPF 3D模型 3D场景

    1.首先得说明的是这并不是真正的3D,模型被导出为一系列的单个图片,例如一个3D户型图,以某个视角旋转360°,渲染出一系列连续的单个图片文件. 2.在Image.MouseMove事件中添加相应代码 ...

  2. JavaScript中call,apply,bind方法的总结。

    why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...

  3. PHP 依赖注入,从此不再考虑加载顺序

    说这个话题之前先讲一个比较高端的思想--'依赖倒置原则' "依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高 ...

  4. Google搜索的几个使用技巧——让你的搜索结果更准确

    对于软件开发人员来说,不知道的内容在网上搜索是再正常不过的了.今天同事在组内分享了几个谷歌搜索的使用技巧,在此自己总结一下,希望可以帮到更多人. 在此之前先要唠叨几句,什么时候用百度,什么时候用谷歌? ...

  5. 揭秘Facebook首个数据中心:全球15亿用户的账户信息都在这里

      投递人 itwriter 发布于 2016-07-14 17:41 评论(0) 原文链接 [收藏]  对于 Facebook.Google 这种体量的科技公司而言,数据中心应该是处于军事级别的保密 ...

  6. android服务之录音功能

    该服务的作用是当打电话时自动录音. 布局文件 布局文件中开启录音服务 <?xml version="1.0" encoding="utf-8"?> ...

  7. CSS3 transform原点设置

    以左上角为原点 -moz-transform-origin: 0 0; -webkit-transform-origin:0 0; -o-transform-origin:0 0; 以右上角给原点 - ...

  8. [转]acm忠告

    多做难题 如果你去问那些牛人“这道题你是怎么想到要用XXX方法的”,我估计大部分人都说不出个所以然来.其实很多情况下都是纯凭直觉考虑到的数个思维方向,这种直觉是需要大量的练习来得到的,没有那么多“为什 ...

  9. tr命令

    tr命令是linux下一个字符处理命令,用途:    字符替换    字符删除    字符压缩形式:tr [OPTION]... SET1 [SET2]接口:输入输出都是标准流,所以要通过管道来调用这 ...

  10. 枚举型Enum和结构型Stuct

    枚举型实质就是使用符号来表示的一组相互关联的数据. Season currentSeason,nextSeason; currentSeason = Season.Spring; nextSeason ...