hello!大家好!我是四舍五入的小晨!
今晚将之前的题目做了一个总结方便查看
文章目录
为什么我要创建这么一个专栏
博主目前计算机专业学习,纯小白一枚。最近在刷浙大pta的题目(最基础的题目),在刷题的途中遇到了许多困难,于是就在网上寻求帮助的时候发现这方面的资源很少,同时听各位大佬说写博客对一个程序员来说很重要,于是就萌生了自己创建一个博客专栏来记录自己刷题的想法,于是就有了这个专栏。
6-1:简单输出整数
1.题目:
本题要求实现一个函数,对给定的正整数N,打印从1到N的全部正整数。
函数接口定义:
void PrintN ( int N );
其中N是用户传入的参数。该函数必须将从1到N的全部正整数顺序打印出来,每个数字占1行。
2.源码:
#define _CRT_SECURE_NO_WARNINGS 1
/* 目的:本题要求实现一个函数,对给定的正整数N,打印从1到N的全部正整数
时间:2021.03.28 22点59分
*/
#include <stdio.h>
void PrintN(int N);
int main()
{
int N;
scanf("%d", &N);
PrintN(N);
return 0;
}
void PrintN(int N)
{
int i;
for (i = 1; i <= N; i++)
printf("%d\n", i);
}
3.执行结果:
4.做题思路:
题目定义了一个void(即不返回值的函数PrintN ),通过键盘输入的N,传入到这个函数内,此时用一个for循环(如果已知循环次数for循环最简单)即可成功实现此功能;
5.总结:
程序写好之后应该至少检验三组数据(当然可以更多),如果三组全部通过,则说明正常(但不排除有特殊情况,至少初学用三组就可以)。如果想写出有价值的代码,方便以后查看的话,我建议在每个程序开头写上程序的目的或者功能,甚至还可以写上时间(说不定看到这串代码的时候还能想起写代码时候和舍友在聊哪个妹子),最后在程序的结尾可以写一些总结、体会和检测代码正确与否的输入输出写到上面(连在哪个编译器里编译的都可以写上哦)。相信这样的代码在日后看来都是一笔不小的财富呢。好了,写到这里就该结束了,欢迎大家点赞,评论和转发哦!后续也会继续发博客分享刷题日常,大家一起加油,冲冲冲!!!
6-2:多项式求值
1.题目:
函数接口:double f( int n, double a[], double x );
裁判测试程序样例:
#include <stdio.h>
#define MAXN 10
double f( int n, double a[], double x );
int main()
{
int n, i;
double a[MAXN], x;
scanf("%d %lf", &n, &x);
for ( i=0; i<=n; i++ )
scanf(“%lf”, &a[i]);
printf("%.1f\n", f(n, a, x));
return 0;
}
/* 你的代码将被嵌在这里 */
2.源码:
double f(int n, double a[], double x)
{ int i ;
double sum = 0.0,x0=1.0;
for (i = 0; i <= n; i++)
{
sum = sum + x0 * a[i];
x0 = x0 * x;
}
return sum;
}
3.解题思路
从0到n求和用for循环即可解决,sum初始值为0,第一次相乘x0*a[i]之后,x0更新,第二次使用时则x0值为x(因为第一次相乘时数组第一个元素下标为0,所以x的0次幂为1),最后返回函数的值即可。
6-3:简单求和。
1.题目:
本题要求实现一个函数,求给定的N个整数的和
函数接口定义:int Sum ( int List[], int N );
其中给定整数存放在数组List[]中,正整数N是数组元素个数。该函数须返回N个List[]元素的和
2.源码:
int Sum(int List[], int N)
{
int total = 0;
int i;
for (i=0; i<N; i++)
{
total= total+ List[i];
}
return total;
}
3.解题思路
本题只需将把list数组里面的每个元素相加,所以使用一个for循环即可,比较简单。
6-4:求自定类型元素的平均
1.题目:
1.1 本题要求实现一个函数,求N个集合元素S[]的平均值,其中集合元素的类型为自定义的ElementType
1.2 函数接口定义:
ElementType Average( ElementType S[], int N );
2.源码
ElementType Average(ElementType S[], int N)
{
int i;
float sum = 0.0;
for (i = 0; i < N; i++)
sum = sum + S[i];
return sum/N; //注意这里的除数是N
}
3.解题思路
typedef给float起了一个别名叫ElementType,分析题意可知题目所求函数功能是求一组数的平均值。这组数储存在一个数据类型为ElementType(即float),数组名为S的数组中,通过宏定义了数组S最多能储存10个元素。本题只需要一个for循环将数组中的所有元素相加并最终返回和与元素的商。
4.总结:
设计函数的思路:
1、函数的返回值类型
2、函数要实现的功能(最重要)
3、函数要接受的参数
a.值传递
值传递时只会将一个变量里的值复制给函数里的变量,因此在函数里面操 作并不会影响函数外面变量里的值,而且由于是复制所以会浪费内存
b.用指针传递地址(和C++里面的引用有点相似)
指针传递的时候只会将外面变量的地址传到函数里面的指针变量,这时候对指针变量解引用后进行操作就可以改变函数外面变量的值了,由于是只传地址所以更快,更少占内存。
6-5:求自定类型元素的最大值
1、题目:
1.1 本题要求实现一个函数,求N个集合元素S[]中的最大值,其中集合元素的类型为自定义的ElementType。
1.2 函数接口定义:
ElementType Max( ElementType S[], int N );
2.源码:
ElementType Max(ElementType S[], int N)
{
float max = S[0];
for (int i = 1; i < N; i++)
{
if (S[i] > max)
max = S[i];
}
return max;
}
3.解题思路:
typedef给float起了一个别名叫ElementType,将数组的第一个元素即S[0]先赋值给变量max,然后遍历数组,如果遇到比第一个元素大的数,则将这个数赋值给max,更新max。将数组第一个元素赋值给max在遍历这样可以避免下面这种情况:
6-6:求单链表结点的阶乘和
1.题目:
3.源码:
int FactorialSum(List L)
{
int sum = 0;//sum用来储存所有结点数据阶乘和
int sum2 = 1;//sum2储存每一个节点数据的阶乘
while(L!=NULL)
{
for (int i = 1; i <= L->Data; i++)
sum2 = sum2 * i;
sum = sum + sum2;
L = L->Next;
sum2=1;//注意此处一定要更新sum2的值
}
return sum;
}
6-7:统计某类完全平方数
1.题目:
2.源码
int IsTheNumber(const int N)
{
int a[10] = { 0 }, n = N, temp, flag = 0;
int m = (int)sqrt(n);//函数返回值为double
if (m *m==n)//证明N是完全平方数
{
while (n != 0)
{
temp = n % 10;
a[temp]++;
n = n / 10;
}
//遍历数组
for (int k = 0; k < 10; k++)
{
if (a[k] >= 2)
{
flag = 1;
return 1;
}
}
if (flag == 0)
return 0;
}
else
return 0;
}
4.思路:
判断一个数是否为完全平方数较为简单,求平方根即可,但是注意sqrt函数的返回值为double因此需要进行强制转换为int。在判断这个数是否有两位数字相同时的思路是定义一个10个元素的数组,从a[0]到a[9]代表数字从0到9。循环取到这个数的最后一位,如果取到2,则对应的数组元素a[2]++,最后遍历数组,元素的值就是对应数字出现的次数。最后记得先将数组初始化为0,这个问题导致我一直过不去测试点。
6-8:求简单阶乘计算
1.题目:
2.代码
int Factorial(const int N)
{
if(N<0)
return 0;
int sum = 1;
for (int j = 1; j <= N; j++)
{
sum = sum * j;
}
return sum;
}
6-9:求统计个位数字
1.题目:
2.代码
int Count_Digit(const int N, const int D)
{
int n = N,temp;
int a[10] = { 0 };
if(N==0&&D==0)//注意此时判断0
return 1;
if(N<0)//如果N为负数可以先变为正数
n=-n;
while (n != 0)
{
temp = n % 10;
a[temp]++;
n = n / 10;
}
return a[D];
}
3.思路
首先应该注意N等于小于零的情况,在判断这个数中某位数字出现次数的思路是定义一个10个元素的数组,从a[0]到a[9]代表数字从0到9。循环取到这个数的最后一位,如果取到2,则对应的数组元素a[2]++,最后返回a[D]的值。
6-10:阶乘计算升级版
1.题目:
2.源码
void Print_Factorial ( const int N ){
int i,j, sum[3000] = {1,0};
int k = 1, temp = 0;
if(N<0)
printf("Invalid input\n");
else{
for( i=2; i<=N; i++)
{
for( j=0; j<k; j++)
{
temp = i * sum[j] + temp; //当前值加上乘积
sum[j] = temp % 10; //每次只存个位数
temp = temp / 10; // 余数不管多少,先存起来。这里的余数就是进位
if(temp>0&&j==k-1)
k++; // 如果有进位,并且数组已经到头了,就增加数组长度
}
}
for ( i=k-1; i>=0; i--) {
printf("%d", sum[i]);
}
printf("\n");
}
}
3.总结:
学习如何通过数组来储存超大数,数组的每个元素对应最后结果的每个数位,如sum[0]代表的就是最后大数的个位,所以最后输出这个数的时候只需要将数组进行从后往前进行遍历即可。最重要的是记住将数组元素和位数联系起来的算法。
6-11:求自定类型元素序列的中位数
1.题目:
2.源码
ElementType Median( ElementType A[], int N )
{
//冒泡排序
for (int i = 0; i <N - 1; i++)
for (int j = 0; j < N -1- i; j++)
{
if (A[j] > A[j + 1])
{
float temp = A[j];
A[j] = A[j + 1];
A[j + 1] = temp;
}
}
if(N%2==0)//偶数个元素
{
int n=N/2;
float ret= A[n-1]>A[n]?A[N-1]:A[n];
return ret;
}
else
{
int n=(N-1)/2;
return A[n];
}
}
3.总结:
注意题目,如果N为偶数应该所返回的是中间两个数中的最大值,而不是相加除以2,而且此时用的排序应该为希尔排序,用冒泡排序在N很大时会超时,如下图所示。
6-12:判断奇偶性
1.题目:
2.代码
int even( int n )
{
if(n==0)
return 1;
else{
if(n%2==0)
return 1;
else
return 0;
}
}
3.总结 :
注意0的情况即可
6-13:折半查找
1.题目:
2.源码:
int Search_Bin(SSTable T, KeyType k){
int head=1,tail=T.length,mid;
while(head<=tail)
{
mid=(head+tail)/2;
if(k==T.R[mid].key)
return mid;
else if(k>T.R[mid].key)//查找的数在mid之后,所以head等于mid的下一个数
head=mid+1;
else
tail=mid-1;//查找的数在mid之前,所以tail等于mid的前一个数
}
return 0;
}