Kaprekar数
时间限制(普通/Java) :
10000 MS/ 30000 MS 运行内存限制 : 65536 KByte
总提交 : 183 测试通过 : 22
总提交 : 183 测试通过 : 22
比赛描述
一个Kaprekar数(雷劈数,或卡普利加数)是个非负整数,将它的平方分成两部分,这两部分之和正好是原来的数字。例如,297是一个Kaprekar 数:297² = 88209, 88 + 209 = 297. 在这里,平方分成的第二部分可以从0开始,但不能是负数。例如, 999是一个Kaprekar 数:999² = 998001, 998 + 001 = 999;但100不是:100² = 10000,100 + 00 = 100, 其中第二部分为0了.
在数学上,假设X是一个非负整数。在十进制计数中,X是一个Kaprekar 数,当且仅当存在非负整数n, A, 和整数B满足下列三个条件::
0 < B <10n
X² = A10n + B
X = A + B
在十进制计数中,常见的Kaprekar数有:
1, 9, 45, 55, 99, 297, 703
输入
输入包含多个测试用例(不超过100)。每个测试用例包括一行。给出一个整数 (位数不超过1000)。一行“0”表示所有输入结束,无需处理此例。
输出
对于每个测试用例,输出一行,依次包含:
l “Case #: ”,#表示序号
l 如果测试用例中的数为Kaprekar数,则输出Yes,否则输出No
样例输入
999
101
4879
0
样例输出
Case 1: Yes
Case 2: No
Case 3: Yes
提示
题目来源
NUPT
/* AC 63MS
#include<iostream>
using namespace std;
#define N 2002
char a[N];
int p[N];
int s[N];
int lenA,lenP,lenS;
bool isKaprekar(){
int i,j,k;
for(i=0;i<lenA;i++){
a[i] -= '0';
}
for(i=0;(i<<1)<lenA;i++){
swap(a[i],a[lenA-1-i]);
}
memset(p,0,sizeof(p));
for(i=0;i<lenA;i++){
for(j=0;j<lenA;j++){
p[i+j] += a[i]*a[j];
}
}
lenP = (lenA<<1)-1;
for(i=0;i<lenP;i++){
p[i+1] += p[i]/10;
p[i] %= 10;
}
while(p[lenP]){
p[lenP+1] += p[lenP]/10;
p[lenP] %= 10;
lenP++;
}
// for(i=lenP-1;i>=0;i--){
// printf("%d",p[i]);
// }
// printf("\n");
for(k=lenP-lenA; k<lenP;k++){
memset(s,0,sizeof(s));
for(i=0;i<k;i++){
s[i] = p[i];
}
for(i=k;i<lenP;i++){
s[i-k] += p[i];
}
lenS = lenP;
while(!s[lenS]){
lenS--;
}
lenS++;
for(i=0;i<lenS;i++){
s[i+1] += s[i]/10;
s[i] %= 10;
}
while(s[lenS]){
s[lenS+1] += s[lenS]/10;
s[lenS] %= 10;
lenS++;
}
for(i=0;i<lenS;i++){
if(s[i]!=a[i]){
break;
}
}
if(i>=lenS){
return 1;
}
}
return 0;
}
int main(){
freopen("test.txt","r",stdin);
int cas=0;
while(scanf("%s",a)==1){
cas++;
lenA = (int)strlen(a);
if(lenA==1 && a[0]=='0'){
break;
}
if(isKaprekar()){
printf("Case %d: Yes\n",cas);
}else{
printf("Case %d: No\n",cas);
}
}
}
*/
// AC 23MS
#include<iostream>
using namespace std;
#define N 2002
char a[N];
int p[N];
int s[N];
int lenA,lenP,lenS;
bool isKaprekar(){
int i,j,k;
for(i=0;i<lenA;i++){
a[i] -= '0';
}
for(i=0;(i<<1)<lenA;i++){
swap(a[i],a[lenA-1-i]);
}
memset(p,0,sizeof(p));
for(i=0;i<lenA;i++){
for(j=0;j<lenA;j++){
p[i+j] += a[i]*a[j];
}
}
lenP = (lenA<<1)-1;
for(i=0;i<lenP;i++){
p[i+1] += p[i]/10;
p[i] %= 10;
}
while(p[lenP]){
p[lenP+1] += p[lenP]/10;
p[lenP] %= 10;
lenP++;
}
// for(i=lenP-1;i>=0;i--){
// printf("%d",p[i]);
// }
// printf("\n");
for(k=lenP-lenA; k<lenP;k++){
if(k>lenA && a[k-1]){
return 0;
}
memset(s,0,sizeof(s));
for(i=0;i<k;i++){
s[i] = p[i];
}
for(i=k;i<lenP;i++){
s[i-k] += p[i];
}
lenS = lenP;
while(!s[lenS]){
lenS--;
}
lenS++;
for(i=0;i<lenS;i++){
s[i+1] += s[i]/10;
s[i] %= 10;
}
while(s[lenS]){
s[lenS+1] += s[lenS]/10;
s[lenS] %= 10;
lenS++;
}
if(lenS != lenA){
continue;
}
for(i=0;i<lenS;i++){
if(s[i]!=a[i]){
break;
}
}
if(i>=lenS){
return 1;
}
}
return 0;
}
int main(){
freopen("test.txt","r",stdin);
int cas=0;
while(scanf("%s",a)==1){
cas++;
lenA = (int)strlen(a);
if(lenA==1 && a[0]=='0'){
break;
}
if(isKaprekar()){
printf("Case %d: Yes\n",cas);
}else{
printf("Case %d: No\n",cas);
}
}
}