#include <stdio.h>
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
class Test {
public:
static void getMaxHw(int sum,int len,std::string&str){
//求各位数字之和为sum,长度为len的最小回文,保存在str
//sum>=2
int times=len/2;
for(int i=0;i<times;++i){
int sum2=sum/2;
int val=sum2>=9?9:sum2;
int valC=48+val;//将数字val转换为相应的字符
str[i]=valC;
str[len-1-i]=valC;
sum-=val;
sum-=val;
}
if(len%2)
str[times]=48+sum;
}
static void getMinHw(int sum,int len,std::string&str){
//求各位数字之和为sum,长度为len的最小回文,保存在str
//sum>=2
int times=len/2;
int val=1;
int val2=2;//2*val
for(int i=0;i<times;++i){
int sub=sum-val2-(len-2*(i+1))*9;
if(sub>0){//如果剩余数字全为9,仍不能凑够sum
val+=sub/2+sub%2;
val2=val+val;//
}
int valC=48+val;
str[i]=valC;
str[len-1-i]=valC;
sum-=val2;
val=0;
val2=0;
}
if(len%2)
str[times]=48+sum;
}
static void getMinHw0(int sum,int len,std::string&str){
//求各位数字之和为sum,长度为len的最小回文,首位从0开始枚举,保存在str
int times=len/2;
for(int i=0;i<times;++i){
int val=0;
int val2=0;//2*val
int sub=sum-val2-(len-2*(i+1))*9;
if(sub>0){
val+=sub/2+sub%2;
val2=val+val;//
}
int valC=48+val;
str[i]=valC;
str[len-1-i]=valC;
sum-=val2;
}
if(len%2)
str[times]=48+sum;
}
static void getNear(int sum,std::string&str1,std::string&str2){
//各位数字之和sum>=2,字符串长度len>=2
//str2为和str1各位数字之和相同,且大于str1的最小回文
int len=str1.size();
int times=len/2;
int index=-1;
bool hasFind=false;
int str2Btstr1=0;
int reserve=0;
int i=0;
for(i=0;i<times;++i){
int val=str1[i]-48;
int val2=val+val;//2*val
int sub=sum-val2;
if(sub<0){
val+=sub/2+sub%2;
val2=val+val;
if(-1==index){
index=i-1;
reserve=sum;
break;
}
}else if((sub-=(len-2*(i+1))*9)>0){
hasFind=true;
val+=sub/2+sub%2;
val2=val+val;
}
int valC=48+val;
str2[i]=valC;
str2[len-1-i]=valC;
if(valC>str1[len-1-i])
str2Btstr1=1;
else if(valC<str1[len-1-i])
str2Btstr1=-1;
else {
//不影响大小性
}
sum-=val2;
}
if(i==times&&len%2){//i==times很有必要
int tmp=sum+48;
if(tmp<str1[times]){
if(-1==index){
index=times-1;
reserve=sum;
}
}else if(tmp>str1[times]){
hasFind=true;
}
str2[times]=tmp;
}
if(hasFind)
return;
if(-1!=index){
while(reserve<2||str2[index]=='9'){//找到可加1的位置
//当内部之和大于2,且本位数字不为9时才能加1
reserve+=2*(str2[index]-48);
--index;
}
++str2[index];
++str2[len-1-index];
reserve-=2;
int tmpLen=len-index*2-2;
std::string subStr(tmpLen,'0');
getMinHw0(reserve, tmpLen,subStr);
int j=0;
for(int i=index+1;i<=len-1-index-1;++i){
str2[i]=subStr[j];
++j;
}
}else{
if(1==str2Btstr1)
return;
else{
index=times-1;
reserve=0;
if(len%2){
reserve+=str2[times]-48;
}
while(reserve<2||str2[index]=='9'){
reserve+=2*(str2[index]-48);
--index;
}
++str2[index];
++str2[len-1-index];
reserve-=2;
int tmpLen=len-index*2-2;
std::string subStr(tmpLen,'0');
getMinHw0(reserve, tmpLen,subStr);
int j=0;
for(int i=index+1;i<=len-1-index-1;++i){
str2[i]=subStr[j];
++j;
}
}
}
}
static string palindrom (string a){
int len=a.length();
int sum=0;
for(int i=0;i<a.length();++i)
sum+=a[i]-48;
if(1>=sum)return "Impossible";
if(1==len)//一位数
if(sum%2){
std::string str(3,'0');
getMinHw(sum,3,str);
return str;
}else{
std::string str(2,'0');
getMinHw(sum,2,str);
return str;
}
//sum>=2,位数>=2
if(sum%2){//和为奇数,那么所求的回文位数也得是奇数
if(0==len%2){//字符串位数为偶数,那么位数为字符串位数+1,各位数字之和为sum的最小回文即为所求
std::string str(len+1,'0');
getMinHw(sum,len+1,str);
return str;
}else{//字符串位数为奇数
std::string strMax(len,'0');
getMaxHw(sum,len,strMax);
if(strMax.compare(a)>0){
std::string str(a);
getNear(sum,a,str);
return str;
}else{
//和为奇数,且和字符串位数、各位数字之和相同的最大回文数小于等于字符串
//那么位数为字符串位数+2(确保位数是奇数),各位数字之和为sum的最小回文即为所求
std::string strMin(len+2,'0');
getMinHw(sum,len+2,strMin);
return strMin;
}
}
}else{//和为偶数
std::string strMax(len,'0');
getMaxHw(sum,len,strMax);
if(strMax.compare(a)>0){
std::string str(a);
getNear(sum,a,str);
return str;
}else{
//和为偶数,且和字符串位数、各位数字之和相同的最大回文数小于等于字符串
//那么位数为字符串位数+1,各位数字之和为sum的最小回文即为所求
std::string strMin(len+1,'0');
getMinHw(sum,len+1,strMin);
return strMin;
}
}
}
};
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main(){
clock_t t1=clock();
std::cout<<"测试用例"<<std::endl;
cout<<Test::palindrom("1234123")<<endl;
cout<<Test::palindrom("1324321")<<endl;
cout<<Test::palindrom("1234444")<<endl;
cout<<Test::palindrom("399212")<<endl;
cout<<Test::palindrom("22222")<<endl;
cout<<Test::palindrom("2213")<<endl;
cout<<Test::palindrom("1014")<<endl;
cout<<Test::palindrom("2231")<<endl;
cout<<Test::palindrom("11111111")<<endl;
cout<<Test::palindrom("111111118")<<endl;
cout<<Test::palindrom("111111139")<<endl;
cout<<Test::palindrom("121")<<endl;
cout<<Test::palindrom("9999")<<endl;
cout<<Test::palindrom("9989")<<endl;
cout<<Test::palindrom("9919")<<endl;
cout<<Test::palindrom("9199")<<endl;
cout<<Test::palindrom("10001")<<endl;
cout<<Test::palindrom("8989")<<endl;
cout<<Test::palindrom("12341234")<<endl;
cout<<Test::palindrom("37532")<<endl;
clock_t t2=clock();
std::cout<<(t2-t1)/double(CLOCKS_PER_SEC)<<std::endl;
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
运行结果: