1023. Have Fun with Numbers (20)

本文介绍了一个算法问题,即判断一个给定的大数与其两倍数的数字排列是否一致。通过使用字符串表示大数并逐一比较对应位置数字的变化来解决此问题。

题目链接:http://www.patest.cn/contests/pat-a-practise/1023

题目:

1023. Have Fun with Numbers (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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 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 file 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

分析:

给你一个数(大数),判断其*2的结果数是否和原数是一样的排列,注意这里不是说给出的数都是1-9的排列,只是题目中举例子用到了1-9而已。

这里设置了ans[]数组,对于原数的每个数都++,对于结果数的每个数都--,那么最后只要判断ans是否全都0就可以判断原数和结果数是否是相同的排列

注意:

考虑到进位,乘以2以后可能会多出一位,而且20位的数字要用string表示而不是用long long表示。

可以看到以下数字的表示范围中long long不够20位。

int ,long , long long类型的范围

unsigned int 0~4294967295
int 2147483648~2147483647
unsigned long 0~4294967295
long 2147483648~2147483647
long long的最大值:9223372036854775807 (刚好19位)
long long的最小值:-9223372036854775808
unsigned long long的最大值:18446744073709551615
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615

AC代码:

#include<stdio.h>
using namespace std;
int ans[10];
char num1[22];
char num2[22];
int main(void){
 //freopen("F://Temp/input.txt", "r", stdin);
 while (scanf("%s", num1) != EOF){
  for (int k = 0; k< 10; k++){
   ans[k] = 0;
  }
  int di = 0, jin = 0,ji = 0;
  int i;
  for (i = 21; num1[i] == 0; i--);//找到最后一位的下标开始计算
  for ( ; i >= 0; i -- ){
   ji = (num1[i] - '0') * 2;
   ans[num1[i] - '0'] ++;//ans对原数相应位的个数++
   di = ji % 10;//*2后的当前位的数字
   num2[i] = di + jin + '0';
   ans[num2[i] - '0'] --;//ans对结果数的相应位的个数--
   jin = (ji + jin) / 10;
  }
  if (jin != 0)ans[jin] ++;
  for (i = 1; i < 10; i++){
   if (ans[i] != 0)break;
  }//判断ans是否全部都为0,若是,则说明原数和结果数是相同的排列
  if (i == 10){
   puts("Yes");
  }
  else {
   puts("No");
  }
  if (jin != 0)printf("%d", jin);
  puts(num2);
 }
 return 0;
}


截图:


——Apie陈小旭

### 关于gcc命令将多个源文件编译为目标文件的解析 #### 问题分析 用户询问是否可以通过`gcc -c fun1.c fun2.c fun.o`将多个源文件分别编译为目标文件,并希望了解其正确用法。 #### 回答 `gcc -c`选项的作用是仅对指定的源文件进行编译,生成目标文件(`.o`),而不进行链接[^1]。因此,`gcc -c fun1.c fun2.c`会分别将`fun1.c`和`fun2.c`编译为`fun1.o`和`fun2.o`两个目标文件[^1]。然而,命令中的`fun.o`并不是有效的输出目标文件名,因为`-c`选项不会生成一个合并的目标文件,而是为每个源文件单独生成对应的目标文件[^1]。 如果需要将多个源文件编译并最终链接为一个可执行文件,可以分两步完成: 1. 使用`gcc -c`分别编译每个源文件为目标文件。 2. 使用`gcc`链接所有目标文件生成最终的可执行文件。 例如: ```bash gcc -c fun1.c -o fun1.o gcc -c fun2.c -o fun2.o gcc fun1.o fun2.o -o final_program ``` 上述命令中,`-c`选项确保了每个源文件被独立编译为目标文件,而最后一步将所有目标文件链接成一个可执行文件`final_program`[^2]。 如果需要在一个命令中完成编译和链接,可以直接列出所有源文件: ```bash gcc fun1.c fun2.c -o final_program ``` 这种方式会自动先将每个源文件编译为目标文件,然后进行链接生成最终的可执行文件[^3]。 需要注意的是,在C语言的编译过程中,头文件的内容会在预处理阶段被包含到源文件中,因此头文件本身不会直接参与编译或链接过程[^3]。此外,为了避免重复定义的问题,头文件中通常只包含声明而不是定义[^4]。 #### 示例代码 以下是一个简单的示例,展示如何使用`gcc`编译和链接多个源文件: ```c // fun1.c #include <stdio.h> void fun1() { printf("This is fun1\n"); } ``` ```c // fun2.c #include <stdio.h> void fun2() { printf("This is fun2\n"); } ``` ```c // main.c void fun1(); void fun2(); int main() { fun1(); fun2(); return 0; } ``` 编译和链接命令: ```bash gcc -c fun1.c -o fun1.o gcc -c fun2.c -o fun2.o gcc -c main.c -o main.o gcc fun1.o fun2.o main.o -o program ``` 运行程序: ```bash ./program ``` #### 输出结果 ``` This is fun1 This is fun2 ``` #### 注意事项 在编译多个源文件时,确保所有源文件之间的函数声明和定义一致,避免链接错误。同时,头文件的使用应遵循“声明在头文件,定义在源文件”的原则,以防止重复定义的问题[^4]。 ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值