1023 Have Fun with Numbers

本文介绍了解决PAT1023问题的方法,该问题要求检查一个给定的20位数加倍后是否形成原数的一个排列。通过使用字符串存储大数并实现大数乘法,结合hashTable来判断排列的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1023 Have Fun with Numbers (20 point(s))

Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!

Now you are suppose to check if there are more numbers with this property. That is, double a given number with kdigits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.

Input Specification:

Each input contains one test case. Each case contains one positive integer with no more than 20 digits.

Output Specification:

For each test case, first print in a line "Yes" if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or "No" if not. Then in the next line, print the doubled number.

Sample Input:

1234567899

Sample Output:

Yes
2469135798

题意是存在一些数(如123456789),将它们加倍后得到的是这个数的另一个排列。本题要求计算输入的2倍,并且判断它是否是输入的另一个排列。

由于至多有20位,不可以用int甚至long long存储。因此用string读入,并将它存储到数组中,然后按照大数加法/乘法的方式处理。对于另一个排列,必然对于每一个数字,有相同的个数。利用Hash思想,只需要用长度为10的int[]来存储数位个数即可。 

关键点:1. 大数加法/乘法;2. hashTable(判断是否是同一个排列)。

注意点:熟悉大数问题(string转数组、数值的高位在字符串数组的低位、进位处理、多余位处理等)

#include<iostream>
#include<string>
using namespace std;
const int N = 21;
int number[N];
int rec[10]={0};
int rec2[10]={0};
int main(void)
{
	string s;
	cin>>s;
	bool flag = true;
	//记录每个数字的个数,并且存入数组
	int len = s.length();
	int dlen;
	for(int i=len-1;i>=0;i--){
		int tmp = s[i]-'0';
		number[len-1-i] = tmp;
		rec[tmp]++;
	} 
	//大数加法
	int carry = 0;
	for(int i=0;i<len;i++){
		int tmp = carry+2*number[i];
		number[i] = tmp % 10;
		carry=tmp/10; 
	} 
	if(carry!=0){
		number[len]=carry;
		dlen = len+1;
		flag = false;
	}
	else dlen = len;
	for(int i=0;i<dlen;i++){
		rec2[number[i]]++;
	}
	for(int i=0;i<=9;i++){
		if(rec[i]!=rec2[i]){
			flag = false;
			break;
		}
	}
	if(!flag) cout<<"No"<<endl;
	else cout<<"Yes"<<endl;
	for(int i=dlen-1;i>=0;i--) cout<<number[i];
	return 0;
}

拓展:

1. <algorithm>定义的count函数和count_if函数,可以用于vector和数组。

链接:https://blog.youkuaiyun.com/lyj2014211626/article/details/69615514

2. PAT1023参考链接:https://blog.youkuaiyun.com/richenyunqi/article/details/79555465

#include<bits/stdc++.h>
using namespace std;
string input,result="";//输入的大整数、2倍后的大整数
int hashTable[10];//辅助数组
void mul(){//大整数乘法
    int num=0;
    for(int i=0;input[i]!='\0';++i){
        int k=2*(input[i]-'0')+num;
        result+=k%10+'0';
        num=k/10;
    }
    if(num!=0)
        result+=num+'0';//如果最终进位不为0,置于result数组末尾
}
int main(){
    cin>>input;
    reverse(input.begin(),input.end());//翻转读取到的数组
    mul();
    for(int i=0;input[i]!='\0';++i){//遍历新数原数两个数组,在相应的hashTable数组下标下进行递增递减
        ++hashTable[input[i]-'0'];
        --hashTable[result[i]-'0'];
    }
    bool yes=(count(hashTable,hashTable+10,0)==10);//遍历整个hashTable数组,看元素0的个数是否为10
    reverse(result.begin(),result.end());//将result数组翻转
    printf("%s\n%s",yes?"Yes":"No",result.c_str());
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值