HDU - 5920 Ugly Problem 求解第一个小于n的回文数
http://acm.hdu.edu.cn/showproblem.php?pid=5920
http://www.cnblogs.com/xudong-bupt/p/4015226.html
把前半部分复制过去,如果太大,那么早到第一个会使得其太大的点,减1,然后对应的中间的变成9
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdlib> #include <ctime> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("3.h","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, int> pii; const ll INF = 1e17; const int inf = 0x3f3f3f3f; const int maxn = 1e3 + 20; char nxt[maxn], str[maxn]; bool is(char str[], int lenstr) { int i = 1, j = lenstr; while (i < j) { if (str[i] != str[j]) return false; ++i; --j; } return true; } void bigCut(char str[], char sub[], char str3[]) { int lenstr = strlen(str + 1), lensub = strlen(sub + 1); // printf("%d\n", lenstr); for (int i = 1; i <= lenstr; ++i) str[i] -= '0'; for (int i = 1; i <= lensub; ++i) sub[i] -= '0'; int use = lenstr; for (int i = lensub; i >= 1; --i, --use) { if (str[use] < sub[i]) { str[use] = 10 + str[use] - sub[i]; int p = use - 1; while (p >= 1 && !str[p]) { str[p] = 9; p--; } str[p]--; } else str[use] -= sub[i]; } for (int i = 1; i <= lenstr; ++i) str[i] += '0'; int to = 0; int p = 1; while (p < lenstr && str[p] == '0') p++; while (p <= lenstr) { str3[++to] = str[p++]; } str3[++to] = '\0'; } char s2[2222]; void findNxt(char str[], int lenstr) { if (is(str, lenstr)) { strcpy(nxt + 1, str + 1); return; } if (str[1] == '1') { bool flag = true; for (int i = 2; i <= lenstr; ++i) { if (str[i] != '0') { flag = false; break; } } if (flag) { for (int i = 1; i <= lenstr - 1; ++i) nxt[i] = '9'; nxt[lenstr] = '\0'; return; } } for (int i = 1,j=lenstr; i <=j; ++i,--j) { s2[j] = s2[i] = str[i]; } for (int i = lenstr / 2 + 1; i <= lenstr; ++i) { if (str[i] < s2[i]) { for(int j=(lenstr+1)/2;;j--) { if(s2[j]=='0') { s2[j]='9'; s2[lenstr-j+1]=s2[j]; } else { s2[j]--; s2[lenstr-j+1]=s2[j]; break; } } break; } } for (int i = 1; i <= lenstr; ++i) nxt[i] = s2[i]; nxt[lenstr + 1] = '\0'; } char res[2222]; char sub[222] = "01"; vector<string> vc; int f; void work() { printf("Case #%d:\n", ++f); vc.clear(); scanf("%s", str + 1); int lenstr = strlen(str + 1); // findNxt(str, lenstr); // printf("%s\n", nxt + 1); while (true) { findNxt(str, lenstr); if (strcmp(str + 1, nxt + 1) == 0) { if (is(str, lenstr)) { vc.push_back(str + 1); break; } else { vc.push_back("1"); sub[0] = '0'; sub[1] = '1'; sub[2] = '\0'; bigCut(str, sub, res); strcpy(str + 1, res + 1); lenstr = strlen(str + 1); continue; } } vc.push_back(nxt + 1); bigCut(str, nxt, res); strcpy(str + 1, res + 1); lenstr = strlen(str + 1); } printf("%d\n", vc.size()); for (int i = 0; i < vc.size(); ++i) { printf("%s\n", vc[i].c_str()); } } int main() { #ifdef LOCAL in(); #else #endif int t; scanf("%d", &t); while (t--) work(); return 0; }
贪心的思路是:最好不要更改前半部分,权值大。
既然选择了远方,就要风雨兼程~
posted on 2017-08-20 19:59 stupid_one 阅读(273) 评论(0) 编辑 收藏 举报