南邮 OJ 1598 Kaprekar数

Kaprekar数

时间限制(普通/Java) :  10000 MS/ 30000 MS          运行内存限制 : 65536 KByte
总提交 : 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);
		}
	}
}



你可能感兴趣的:(ACM,南邮OJ,Kaprekar数)