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

题意

将一个正整数 $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. swift---不同字体大小不同颜色label富文本设置

    agreeDeal = UILabel() //富文本,不同字体颜色大小和颜色 let labelString = "登录注册,表示您同意<服务条款及隐私政策>"as ...

  2. 分享:关于之前锤子手机刷MIUI之后,现在有事跌宕起伏的刷回了Smartisan OS!

     序言: 距离上次把锤子手机刷成MIUI之后已经一个半月了,我是一个刷机党,一个半月足够让我适应一个系统,了解一个系统.刷机有风险,不过我愿意冒这个风险,因为兴趣,没别的.刷机之后,肯定是有问题的,没 ...

  3. [BZOJ1854][Scoi2010]游戏(二分图匹配/并查集)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1854 分析:很裸的一道二分图匹配对吧,但是在hzwer的blog上看见神奇的并查集做法 ...

  4. struct socket 结构详解

    Socket数据结构网络协议CC++     用户使用socket系统调用编写应用程序时,通过一个数字来表示一个socket,所有的操作都在该数字上进行,这个数字称为套接字描述符.在系统调用 的实现函 ...

  5. android 资讯阅读器(二)

    接着上次的博客,上次移植完了tab以后整个app的框架就算是定下来了. 本次目标: 1.数据的获取与展示(ListView) 2.官方的下拉刷新效果(SwipeRefreshLayout) 3.数据接 ...

  6. 十天冲刺---Day7

    站立式会议 站立式会议内容总结: 燃尽图 照片 两个人编码其实效率挺高的.但是在一些方面,比如说页面UI的编写,会非常吃力,很难达到自己的效果. 由于埋头在编码,所以issues的增加随之停止. 有点 ...

  7. springMVC之web.xml配置

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  8. JAVA file文件操作

    /** *文件重命名 * @param oldname 原来的文件名 * @param newname 新文件名 */ @RequestMapping("renameFile") ...

  9. [转]制作png格式透明图片的简易方法

    原文地址:http://blog.csdn.net/zhouyingge1104/article/details/24460743 photoshp之类的专业软件太复杂,其实,制作透明图标有比较简易的 ...

  10. hdu2665 && poj2104划分树

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 47066   Accepted: 15743 Ca ...