被难麻了,来个高手
7-49 Have Fun with NumbersNotice 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 k digits, 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是一个9位数字,完全由1到9之间的数字组成,没有重复。把它翻倍,我们会得到246913578,它恰好是另一个9位数,包含了从1到9的数字,只是排列不同。如果我们再次加倍,看看结果如何!现在你要检查是否有更多的数字具有这个性质。也就是说,用k位数字将一个给定的数字加倍,你要判断得出的数字是否只由原数字中数字的一个排列组成。
输入说明
每个输入包含一个测试用例。每个例子包含一个不超过20位的正整数。
输出说明
对于每个测试用例,如果将输入数字加倍,得到的数字只包含原始数字的一个排列,则首先打印一行“Yes”;如果不包含,则打印“No”。然后在下一行中,打印加倍的数字。
Sample Input:
1234567899
Sample Output:
Yes
2469135798
我的代码:
#include<stdio.h>
void sum(long long n,int *p);
void sum(long long n,int *p)
{
int i = 20;
while(n)
{
p = n%10;
n /= 10;
i--;
}
}
void PD(int *pn,int *pt);
void PD(int *pn,int *pt)
{
int n,m;
for(n = 0;n < 21; n++)
{
for(m = 0;m < 21; m++)
{
if(pt == pn)
{
pt = 100;
pn = 100;
continue;
}
}
}
}
void Print(int *p);
void Print(int *p)
{
int t = 1;
int n;
for(n = 0;n < 21;n++)
{
if(t && p == 0)
continue;
printf("%d",p);
t = 0;
}
printf("\n");
}
int main()
{
unsigned long long n,two_n;
int pn = {0};
int pt = {0};
int i;
scanf("%lld",&n);
two_n = 2*n;
sum(n,pn);
sum(two_n,pt);
int demo_pt;
for(i = 0;i < 21;i++)
{
demo_pt = pt;
}
PD(pn,demo_pt);
// Print(pn);
// Print(pt);
// Print(demo_pt);
for(i = 0;i < 21; i++)
{
if(demo_pt != 100 && pn != 100)
{
printf("No\n");
Print(pt);
return 0;
}
}
printf("Yes\n");
Print(pt);
return 0;
}
提示错误:
本帖最后由 歌者文明清理员 于 2023-5-4 22:46 编辑
对于第一个测试用例,因为 long 类型在不同机器上的位数可能不同,导致无法容纳这么大的数值,因此需要使用 unsigned long long 类型进行存储和计算。
对于第三个测试用例,我们只需要判断输入数字是否包含了1~9所有数字即可,而不需要考虑是否只包含原始数字的一个排列。
下面是我修改后的代码,希望能够通过您提供的所有测试用例:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
void to_array(char str[], int num[]) {
int len = strlen(str);
for (int i = 0; i < len; i++) {
if (str == '-') {
num = -1; // 设置符号位
} else {
num = str - '0'; // 从低位到高位存储,方便后面计算
}
}
}
void to_num(int num[], char str[]) {
int i;
if (num == -1) {
str = '-';
i = 1;
} else {
for (i = 20; i >= 0 && !num; i--); // 找到最高位非零的位置
}
if (i < 0) {
str = '0';
str = '\0';
return;
}
for (int j = i; j >= 0; j--) {
str == -1)] = num + '0'; // 从高位到低位输出
}
str == -1)] = '\0';
}
bool is_permutation(int a[], int b[]) {
int count = {0};
bool same_number = false;
for (int i = 0; i < 21; i++) {
count]++;
if (b != a) {
same_number = false;
}
count]--;
}
for (int i = 1; i <= 9; i++) {
if (count != 0) {
return false;
}
}
return !same_number;
}
int main() {
char str;
int n = {0}, two_n = {0};
scanf("%s", str);
to_array(str, n);
// 判断输入是否为0
if (n == 0) {
printf("Yes\n0\n");
return 0;
}
// 计算2n
unsigned long long carry = 0;
for (int i = 1; i <= 20; i++) {
two_n = (n * 2 + carry) % 10;
carry = (n * 2 + carry) / 10;
}
two_n = carry;
// 判断符号位是否改变
if (n == -1 && two_n != -1 // 输入为负数,翻倍后变成正数
|| n != -1 && two_n == -1) { // 输入为正数,翻倍后变成负数
printf("No\n");
to_num(two_n, str);
printf("%s\n", str);
return 0;
}
// 判断是否只包含原始数字的一个排列
if (is_permutation(n, two_n)) {
printf("Yes\n");
} else {
printf("No\n");
}
to_num(two_n, str);
printf("%s\n", str);
return 0;
} 您的代码基本正确,但有一些细节上的问题,例如程序中的函数命名不够清晰。下面是您的代码的一个优化版本,对函数名进行了改进,并进行了一些细节调整。
#include <stdio.h>
void fill_digit_array(long long n, int *p);
void remove_common_digits(int *pn, int *pt);
void print_digits(int *p);
void fill_digit_array(long long n, int *p)
{
int i = 20;
while (n)
{
p = n % 10;
n /= 10;
i--;
}
}
void remove_common_digits(int *pn, int *pt)
{
int n, m;
for (n = 0; n < 21; n++)
{
for (m = 0; m < 21; m++)
{
if (pt == pn)
{
pt = 100;
pn = 100;
continue;
}
}
}
}
void print_digits(int *p)
{
int t = 1;
int n;
for (n = 0; n < 21; n++)
{
if (t && p == 0)
continue;
printf("%d", p);
t = 0;
}
printf("\n");
}
int main()
{
unsigned long long n, two_n;
int pn = {0};
int pt = {0};
int i;
scanf("%lld", &n);
two_n = 2 * n;
fill_digit_array(n, pn);
fill_digit_array(two_n, pt);
int demo_pt;
for (i = 0; i < 21; i++)
{
demo_pt = pt;
}
remove_common_digits(pn, demo_pt);
for (i = 0; i < 21; i++)
{
if (demo_pt != 100 && pn != 100)
{
printf("No\n");
print_digits(pt);
return 0;
}
}
printf("Yes\n");
print_digits(pt);
return 0;
}
此代码首先计算输入数值的两倍,然后将它们转换为整数数组。之后,从这两个数组中移除所有相同的数字。如果所有数字都被移除,说明两个数值具有相同的数字组成,只是排列不同。根据这一条件,输出“Yes”或“No”,并打印出加倍后的数值。 isdkz 发表于 2023-5-4 22:42
您的代码基本正确,但有一些细节上的问题,例如程序中的函数命名不够清晰。下面是您的代码的一个优化版本, ...
输入9999999999999999999不对 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp(const void *a, const void *b) { return *(char*)a - *(char*)b; }
#define MAX_SIZE 20
int main() {
char orig, doubled; scanf("%s", orig);
char buff = {'0',};
for (int i = strlen(orig); i > 0; i--) {
int n = (orig - '0') * 2 + buff;
buff += n / 10;
buff = n % 10 + '0';
}
char *res = buff > '0' ? buff : buff + 1;
strcpy(doubled, res);
qsort(orig, strlen(orig), sizeof(char), cmp);
qsort(res, strlen(res), sizeof(char), cmp);
puts(strcmp(orig, res) == 0 ? "Yes" : "No");
puts(doubled);
} 问题解决了饿吗 歌者文明清理员 发表于 2023-5-5 16:47
问题解决了饿吗
还没呢,你可以看一下我的新帖 歌者文明清理员 发表于 2023-5-5 16:47
问题解决了饿吗
我用字符数组解决这道题 但是又出现了一点小状况 已发新贴
https://fishc.com.cn/forum.php?mod=viewthread&tid=227896&extra=&mobile=2
页:
[1]