A number that will be the same when it is written forwards or backwards is known as a palindromic number. For example, 1234321 is a palindromic number.
We call a number generalized palindromic number, if after merging all the consecutive same digits, the resulting number is a palindromic number. For example, 122111 is a generalized palindromic number. Because after merging, 122111 turns into 121 which is a palindromic number.
Now you are given a positive integer N, please find the largest generalized palindromic number less than N.
There are multiple test cases. The first line of input contains an integer T (about 5000) indicating the number of test cases. For each test case:
There is only one integer N (1 <= N <= 1018).
For each test case, output the largest generalized palindromic number less than N.
4 12 123 1224 1122
11 121 1221 1121
Solution:
看到此题,首先想到是贪心或者深搜的做法,但对于贪心,感觉比较烦琐PS:可能用贪心也做不了,弱菜一个。
深搜方法:
因为压缩后要成为一个回文串,所以可以利用这一点来剪枝
为了利用这一点,在深搜时保持状态
char* compress //搜索到当前位置为止,压缩后的数组
int compresslen //压缩后的的数组长度
int ind //下一个要搜的位置
我们也看到压缩后的回文串肯定是一个奇数长度的串,也就有一个中间的点,如此,我便在状态中加入了这个点
int peak//回文串中间点
还保存了一个搜索到目前为止,对于前面的字符是否有所改变
bool changed //前面对应的字符串是否已经改变
结束搜索:
是否有已经加入回文串中间点,并且余下没有搜索的字符串 等于压缩字符串成为一个回文串所需要的最少字符
或者没有回文串中间点,可以直接剪枝等等的先剪了。
进一步:
枚举当前字符的范围,并讨论是否可压缩,是否设置中间点,当然这两类情况需要比较哪种情况更好。
由于深搜索没有考虑10000 100001等情况,所以后面特殊讨论。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 50; char s[N]; char globalchange[N]; char stype1[N]; char stypy2[N]; int len; bool dfs(char* compress,int compresslen,int ind,bool changed,int peak) { if(len == 1) {globalchange[0] = s[0] - 1;return true;} if((peak + 4) && (2*peak == compresslen -1 +len -ind)) { if(changed) { for(int t = ind; t<len; t++) globalchange[t] = compress[len-t-1]; return true; } int flag = 0; for(int t = ind; t<len; t++) { if(s[t] < compress[len-t-1] && !flag) return false; if(s[t] > compress[len-t-1]) flag = 1; globalchange[t] = compress[len-t-1]; } if(flag) return true; else return false; } else if((peak+4) && (2*peak > compresslen - 1 + len - ind)) return false; else if(!(peak+4) && compresslen > len-ind-1) return false; for(char loopi = changed?'9':s[ind]; loopi >= '0'; loopi--) { globalchange[ind] = loopi; bool res = false; //peak; if((peak+4)) { if(compress[compresslen-1] == loopi) res = dfs(compress,compresslen,ind+1,changed || (loopi != s[ind]),peak); else { if(compress[peak-(compresslen-peak-1)-1] == loopi) { compress[compresslen] = loopi; res = dfs(compress,compresslen+1,ind+1,changed || (loopi != s[ind]),peak); } } if(res) return true; } else { memset(stype1,0,sizeof(stype1)); memset(stypy2,0,sizeof(stypy2)); if(compresslen != 0 && compress[compresslen-1] == loopi) res =dfs(compress,compresslen,ind+1,changed || (loopi != s[ind]),peak); else { compress[compresslen] = loopi; res = dfs(compress,compresslen+1,ind+1,changed || (loopi != s[ind]),peak); } if(res) {strcpy(stype1,globalchange);} if(compresslen!=0 && compress[compresslen-1] == loopi) res = dfs(compress,compresslen,ind+1,changed || (loopi != s[ind]),compresslen-1); else { compress[compresslen] = loopi; res = dfs(compress,compresslen+1,ind+1,changed || (loopi != s[ind]),compresslen); } if(res) {strcpy(stypy2,globalchange);} if(stype1[0] != '\0' || stypy2[0] != '\0'){ int r = strcmp(stype1,stypy2); if(r > 0) strcpy(globalchange,stype1); else strcpy(globalchange,stypy2); return true; } } } return false; } bool change() { if((s[0] == '1') && (s[len-1] >='0' && s[len-1] <= '1')) { int i =1; int flag = 0; while(i<len-1) { if(s[i] != '0') return false; i++; } for(int j=0;j<len-1;j++) printf("9"); printf("\n"); return true; } return false; } int main() { int test; scanf("%d",&test); while(test -- ) { scanf("%s",s); len = strlen(s); if((len == 1) && s[0] == '1') {printf("0\n");continue;} if(change()) continue; memset(globalchange,0,sizeof(globalchange)); char temp[N]; memset(temp,0,sizeof(temp)); bool res = dfs(temp,0,0,false,-4); printf("%s\n",globalchange); } return 0; }