您的位置:首页 > 其它

SPOJ #5 The Next Palindrome

2014-02-06 02:43 316 查看
"not more than 1000000 digits" means an efficient in-place solution is needed. My first solution was string<->int conversion based. It worked for small ints, but got TLE with large numbers.

Thanks to http://www.bytehood.com/spoj-the-next-palindrome/418/ that shed lights on me. The key idea is the same as my first idea: simply keep increasing digits near the center digit(s), and we only need figure out left half of the digits since it is mirrored palindrome.

(I saw a lot of rejudge requests in SPOJ comments.. several erroneous results got returned from AC code. Mine's also rejected due to wrong answer - I think rejudge is needed)

Corner cases are important to this problem: single digits, all 9s, carry-over situation etc. Here is my code:

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

int dCarry = 0;
int findLgRInx(char *str, int len, int i_l)
{
int i_mis = -1;
int i = i_l;
while(i-- >= 0)
{
if(str[i] > str[len - 1 - i])
{
i_mis = i;
break;
}
}
return i_mis;
}

void incLHalf(char *str, int len, int i_l)
{
int i = i_l;
while(i >= 0)
{
int d = str[i] - '0';
if(d < 9)
{
str[i] = (d + 1) + '0';
return;
}
else
{
str[i] = '0';
if(i > 0)
{
int nd = str[i-1]-'0';
if(nd < 9)
{
str[i-1] = (nd + 1) + '0';
return;
}
}
else
{
dCarry = 1;
return;
}
}
i--;
}
}

void copyl2r(char *str, int len, int i_l)
{
int i = i_l;
while(i >= 0)
{
str[len-i-1] = str[i];
i--;
}
}

void calc_next_palin(char *str)
{
unsigned len = strlen(str);
if(len == 1)
{
int i = atoi(str);
cout << (i + 1) + i / 9 << endl;
return;
}

int i_l = 0, i_r = 0;
if(len % 2 == 0)
{
i_l = len / 2 - 1;
i_r = len / 2;
int i_mis = findLgRInx(str, len, i_l);
if(i_mis != -1)
{
copyl2r(str, len, i_mis);
cout << str << endl;
return;
}
else
{
incLHalf(str, len, i_l);
copyl2r(str, len, i_l);
if(dCarry == 0)
{
cout << str << endl;
}
else
{
cout << "1" << str << "1" << endl;
}
return;
}
}
else    //odd
{
int i_c = len / 2;
int i_mis = findLgRInx(str, len, i_c + 1);
if(i_mis != -1)
{
copyl2r(str, len, i_mis);
cout << str << endl;
}
else
{
int dmid = str[i_c] - '0';
if(dmid < 9)
{
str[i_c] = (dmid + 1) + '0';
}
else
{
str[i_c] = '0';
incLHalf(str, len, i_c - 1);
copyl2r(str, len, i_c);
}
if(dCarry == 0)
{
cout << str << endl;
}
else
{
cout << "1" << str << "1" << endl;
}
}
return;
}
}

int main()
{
int cnt; cin >> cnt;
if(cnt == 0) return 0;

//
while(cnt --)
{
string str; cin >> str;
calc_next_palin((char*)str.c_str());
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: