题目:手动输入一个数组(int),长度自定,将数组内容去重,并输出值
输入:1 2 3 2 4 2 5 2 6 2
输出:1 3 4 5 6
思路:
1.先找到重复数字,能够两两对比的方法,可以进行选择排序
2.将重复数字改为标记数字,这里为了方便我选的是0当然,为了避免与数组中值重复,导致出错,可以用 stdlib 头文件下面的 rand()函数获取一个随机值,将其与数组内容对比,没有相等的就作为标记值
3.将标记数组后移
//创建测试数组,后续可以添加scanf来手动输入数组
//测试数组1
//int nums[10] = {1,2,3,2,4,2,5,2,6,2};
//测试数组2
int nums[10] = {1,1,1,1,1,1,1,1,1,1};
//值交换容器
int p;
//标记值计数器
int count = 0;
//两层循环进行选择排序,这里是从尾端开始的
for (int i = 9; i >= 0; --i) {
for (int j = 0; j < i; ++j) {
//外层循环选择的数与内层循环选择的数相等时,改成标记数字
if(nums[i] == nums[j]){
nums[i] = 0;
//优化算法用的,记录有几个标记值
count++;
}
//因为是反向遍历,所以需要把标记数字后移到尾部
//不加count也能得出答案,但是遍历的次数增加了
// 因为每执行一次上一层循环,就将标记值打到了数组后方,只需要遍历除了标记值的地方就行
for (int k = i; k < 10 - count; ++k) {
//判断当前位置是不是标记值,是标记值就后移
if(nums[k] == 0) {
p = nums[k];
nums[k] = nums[k + 1];
nums[k + 1] = p;
}
}
}
}
//打印输出标记值之前的数字
for (int i = 0; i < 10 - count; ++i) {
printf("%d ",nums[i]);
}
每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。
输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号
。其中准考证号
由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。
考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。
对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。
4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4
3310120150912002 2
3310120150912119 1
思路:
考生信息是一个结构体,只需将其创建一个链表串联起来即可,用基本的链表的创建销毁,增删改查,即可的到信息,没有涉及太多的算法
#include
#include
#include
//创建结构体,a:准考证号,sjh:上机号,zwh:座位号,next:结构体指针
typedef struct Note{
char a[20];
int sjh;
int zwh;
struct Note* next;
}Note;
//创建新节点
void Note_new_head(Note *note , char *a, int sjh, int zwh);
//找到节点并输出
void find_out_info(Note *note, int sjh);
int main(){
//创建考生信息结构体的头节点,将其指向空
Note note;
note.next = NULL;
//创建结构体的基本数据容器,包括准考证号,试机座位号,考试座位号
char a[20];
int sjh,zwh;
//记录考生信息的条数
int N;
scanf("%d",&N);
//循环记录考生的信息
for(int i = 0;i < N ;++i){
//键盘记录考生信息
scanf("%s %d %d",a,&sjh,&zwh);
//调用头插法,插入信息链表
Note_new_head(¬e,a,sjh,zwh);
}
//创建查询数量容器,通过键盘键入
int num;
scanf("%d",&num);
//创建记录上机号容器
int find_sjh;
//循环记录值,并调用找寻输出函数
for(int i = 0; i < num;++i){
scanf("%d",&find_sjh);
//调用找寻输出函数
find_out_info(¬e,find_sjh);
}
return 0;
}
//创建新节点,并使用头插法插入链表
void Note_new_head(Note *note , char *a, int sjh, int zwh){
//创建新节点,并分配空间
Note* new_note = (Note *)malloc(sizeof(Note));
//赋值
strcpy(new_note->a,a);
new_note->sjh = sjh;
new_note->zwh = zwh;
//头插
new_note->next = note->next;
note->next = new_note;
}
//创建查询输出函数
void find_out_info(Note *note, int sjh){
//创建指针指向头节点
Note* p = note->next;
//遍历链表,找到符合的上机号,并输出其准考证号和座位号
while(p != NULL){
if(p->sjh == sjh){
printf("%s %d\n",p->a,p->zwh);
return;
}
p = p->next;
}
}
本题要求实现一个打印非负整数阶乘的函数。
void Print_Factorial ( const int N );
其中N
是用户传入的参数,其值不超过1000。如果N
是非负整数,则该函数必须在一行中打印出N
!的值,否则打印“Invalid input”。
#include
void Print_Factorial ( const int N );
int main() {
int N; scanf("%d", &N);
Print_Factorial(N);
return 0;
}
/* 你的代码将被嵌在这里 */
15
1307674368000
思路:我第一此写的时候,只是简单的使用for循环解决,计算结果,最开始时使用的int的数据类型接受结果,最后测试结果发现只有部分正确,提示上面写的计算1000的阶乘时错误了,我就开始思考了
void Print_Factorial ( const int N ){
//处理特殊情况:<0 >1000
if(N < 0 || N > 1000){
printf("Invalid input");
return;
}
//创建阶乘容器
unsigned long long factorial = 1;
for(unsigned long long i = 1;i <= N;++i){
factorial *= i;
}
printf("%lld\n",factorial);
//结果:unsigned long long的范围不足以储存1000的阶乘
}
所以我改变思路,从数组出发,简单的进位计算就解决了
数组的每一个位置值储存结果的每一位值,每一个值都需要去与阶乘的下一个数进行乘法计算,计算完的结果的个位数就是这个位置的值,也就是%10即可的得到答案,然后将结果除个10,就是需要进位的数,将除10后的值与下一位值和阶乘的下一个数乘法计算后的结果相加再%10就是下一位的值,如此往复,就是答案
我的代码的注释写的很详细,可以看看,就知道了
void Print_Factorial(const int N){
//处理特殊情况
if(N > 1000 || N < 0){
printf("Invalid input");
return;
}
//定义数组容器
int factorial_arr[3000] = {0};
//特殊情况隔离,1和0的阶乘为1;
factorial_arr[0] = 1;
//设置基础长度为1
int length = 1;
//设置位相乘容器
int produnt;
//设置相乘进位容器
int carry_product;
//阶乘
for(int i = 2;i <= N;++i){
//第一遍初始化进位容器,之后每次循环都重置进位容器
carry_product = 0;
//将length长度范围内的所有位相乘取余
for(int j = 0;j < length;++j){
//第一遍注入个位相乘结果给product
//之后把相乘后需要进位的carcarry_product加上注入
produnt = factorial_arr[j] * i + carry_product;
//将位相乘的结果取余注入当前遍历到的位
factorial_arr[j] = produnt % 10;
//记录相乘后的进位值
carry_product = produnt / 10;
}
//当前的carcarry_product是超过length长度的进位值
while(carry_product){
//将进位值按照长度依次注入阶乘容器
factorial_arr[length] = carry_product % 10;
carry_product /= 10;
//将长度增加
length++;
}
}
//打印数组值
for(int i = length - 1;i >= 0;--i){
printf("%d",factorial_arr[i]);
}
printf("\n");
}