csdn英雄会(pongo)题解之回文数--源代码、测试用例、运行结果

来源:互联网 发布:网络维护难点分析 编辑:程序博客网 时间:2024/05/21 05:08

#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>=2int 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>=2int times=len/2;int val=1;int val2=2;//2*valfor(int i=0;i<times;++i){int sub=sum-val2-(len-2*(i+1))*9;if(sub>0){//如果剩余数字全为9,仍不能凑够sumval+=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开始枚举,保存在strint times=len/2;for(int i=0;i<times;++i){int val=0;int val2=0;//2*valint 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*valint 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时才能加1reserve+=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,位数>=2if(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 //提示:自动阅卷结束唯一标识,请勿删除或增加。
运行结果:







0 0
原创粉丝点击