http://acm.hdu.edu.cn/showproblem.php?pid=5920
把前半部分复制过去,如果太大,那么早到第一个会使得其太大的点,减1,然后对应的中间的变成9
#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;
}
View Code
贪心的思路是:最好不要更改前半部分,权值大。