pta(浙大第四版)五道经典练习题①

目录

①8-1-7 数组循环右移

②8-2-5判断回文字符串

③平面向量加法

④、圆形体体积计算

⑤、判断满足条件的三位数


①8-1-7 数组循环右移

题述:本题要求实现一个对数组进行循环右移的简单函数:一个数组a中存有n(>0)个整数,将每个整数循环向右移m(≥0)个位置,即将a中的数据由(a0​a1​⋯an−1​)变换为(an−m​⋯an−1​a0​a1​⋯an−m−1​)(最后m个数循环移至最前面的m个位置)。

函数接口定义:

void ArrayShift( int a[], int m, int n );

其中a[]是用户传入的数组;n是数组的大小;m是右移的位数。函数ArrayShift须将循环右移后的数组仍然存在a[]中。

输入样例:

6 2
1 2 3 4 5 6

输出样例:

5 6 1 2 3 4
#include<stdio.h>

void Arrayshift(int* ptr, int m,int n)
{
	int i = 0, j = 0;
	for (i = 0; i < m; i++)//循环一次就后移一位
	{
		int tmp = *ptr;
		for (j = 0; j < n - 1; j++)
		{
			ptr[j] = ptr[j + 1];
		}
		ptr[n - 1] = tmp;
	}
}
int main()
{
	int n = 0, m = 0;
	scanf("%d", &n);
	int i = 0;
	int a[1000];
	for (i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
	}
	scanf("%d", &m);
	Arrayshift(a, m, n);
	for (i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

 解析:和左旋字符串的解法基本一样,不过本题只针对整形罢了

1、因为你传入的是a--数组名(首元素的地址),所以用指针接收,Arrayshift数组就不用返回int*了。在函数内部就可以修改a数组

2、不可将函数内部改为int* tmp = ptr, ptr[n-1] = *tmp,什么意思呢?tmp存的是ptr的地址(数组a第一个元素的地址&a[0]),而for循环中第一次*ptr = *(ptr+1),假如我输入四个数据,1 2 3 4,那么1被赋值为2,而*tmp = a[0] = 2了,所以你在for循环途中就改变了*tmp,所以一定不行!

②8-2-5判断回文字符串

题述:判断回文字符串:判断输入的一串字符是否为“回文”,所谓 “回文”是指顺读和倒读都一样的字符串,如“XYZYX”和“xyzyx”都是回文。试编写相应程序。

两种方法解析(来自于其他文章参考,我主要讲解思路)其实还有一种方法翻转原串,这里就不说了

一、前后指针对比

思路:回文字符串呈现对称结构,所以可以用指针遍历字符串,一个指针指向头,另一个指针指向尾,遍历字符串即可。注:这里说的指针就是用数组表示的,因为数组本质可以用指针表示

#include<stdio.h>
#include<string.h>
int main()
{
	char s[90];
	gets(s);//因为你输入的字符串可能含有空格等
	int right = strlen(s)-1;
	int left = 0,flag = 1;
	while (left < right)
	{
		if (s[left++] != s[right--])
		{
			flag = 0;//如果有一次不等了,就可说明该字符串不是回文字符串
			break;
		}
	}
	printf("%s是否为回文字符串:\n", s);
	(flag) == 1 ? printf("YES!\n") : printf("NO!\n");
	return 0;
}

二、折半对比

思路:还是第一个元素和最后一个元素比较,然后每次判断完,i++,就可进行下一次判断,总共比较到字符串长度的一半的次数即可完成比较

#include<stdio.h>
#include<string.h>

int main()
{
	char s[90];
	gets(s);
	int len = strlen(s);
	int left = 0, flag = 1;
	for (int i = 0; i < len / 2; i++)//比较1en/2次即可,也就是比较一半就可以遍历字符串
	{
		if (s[i] != s[len-1-i])
		{
			flag = 0;
			break;
		}
	}
	printf("%s是否为回文字符串:\n", s);
	(flag) == 1 ? printf("YES!\n") : printf("NO!\n");
	return 0;
}

③平面向量加法

题述:平面向量加法:输入两个二维平面向量V1=(x1,y1)和V2=(x2,y2)的分量,计算并输出两个向量的和向量。试编写相应程序。坐标输出小数点后一位(注意不能输出-0.0)

思路:这道题难就难在因为输出不能有-0.0,什么意思呢?在计算机中,0.0和-0.0是不同的浮点数。虽然它们在数学上相等,但它们在计算机内部的表示方式是不同的。如果程序输出了-0.0,可能会在某些情况下引起问题。为了避免这种问题,通常建议在输出浮点数时,将所有小于0.0但是大于-0.05的数都输出为0.0,而不是输出-0.0。就是如果输出的小数为0,则需将其输出为0,而不是输出-0.0 。在-0.05到0之间的数(不包括-0.05,包括0也行不包括0也行),会因为你保留一位小数而变成-0.0而出错,所以要直接置为0。比如-0.04如果保留一位小数,会因为四舍五入变成-0.0,你此时就要把他变成0,那为什么要从大于-0.05的数开始判断呢?-0.06开始呢?不行,因为-0.05本身保留一位小数四舍五入会变成-0.1,不会产生-0.0和0迷惑的情况

#include<stdio.h>

typedef struct p
{
	double x1, x2, y1, y2;
	double sum1, sum2;
}p;
int main()
{
	p vector = { 0 };
	scanf("%lf %lf %lf %lf", &vector.x1, &vector.x2, &vector.y1, &vector.y2);
	vector.sum1 = vector.x1 + vector.y1;
	vector.sum2 = vector.x2 + vector.y2;
	if (vector.sum1 > -0.05 && vector.sum1 < 0)
	{
		vector.sum1 = 0.0;
	}
	if (vector.sum2 > -0.05 && vector.sum2 < 0)
	{
		vector.sum2 = 0.0;
	}
	printf("(%.1lf %.1lf)", vector.sum1, vector.sum2);
	return 0;
}

④、圆形体体积计算

题述:圆形体体积计算器:设计一个常用圆型体体积的计算器,采用命令方式输入1、2、3,分别选择计算球体、圆柱体、圆锥体的体积,并输入计算所需的相应参数。该计算器可支持多次反复计算,只要输入1、2、3,即计算相应圆形体的体积;如果输入其他数字,将结束计算。

思路:主要给函数指针的解法,这道题很明显可以用switch来求解,这个方法相对简单,但是我提供一种新思路。

#include<stdio.h>
//sphere:范围,领域,球体,社会阶层,势力范围  面积:三分之四πr的平方
//cylinder:圆柱体,圆筒,汽缸                面积:πr的平方*高h
//cone:圆锥体							   面积:三分之一πr的平方*高h
#define π 3.14
double sphere(double r,double h)
{
	return 3.0 / 4 * π * r * r;
//求球体体积跟高度无关,但是为了保持这三个函数的参数一致,所以会加一个h
//但无论h输入多少,都不影响实际运算
}
double cylinder(double r, double h)
{
	return π * r * r * h;
}
double cone(double r, double h)
{
	return 1.0 / 3 * π * r * r * h;
}
int main()
{
	int x = 0;
	double r = 0, h = 0;
	double(*pfArr[4])(double, double) = { NULL,sphere,cylinder,cone };//转移表的应用
	printf("请选择:>");
	scanf("%d", &x);
	if (x >= 1 && x <= 3)
	{
		printf("请输入两个参数:>");
		scanf("%lf %lf", &r, &h);
		double ret = pfArr[x](r, h);
		printf("面积为%lf\n", ret);
	}
	else
	{
		printf("选择错误,终止计算!\n");
	}
	return 0;
}

⑤、判断满足条件的三位数

题述:判断满足条件的三位数:编写一个函数,利用参数传入一个3位数number,找出101~number之间所有满足下列两个条件的数字:它是完全平方数,又有两位数字相同(如144、676等)。函数返回找出这样的数字的个数,并编写主函数。

思路:

了解完全平方数:

完全平方指用一个整数乘以自己(如1*1,2*2等)。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。比如9=3*3,则9就是一个完全平方数。其是一个非负数,而一个完全平方数的项有两个。不要与完全平方式混淆。

#include <stdio.h>
#include <math.h>

int search(int n)
{//函数返回【101~n】区间内所有满足条件的数的个数
//因为10*10=100,而100不在区间范围内,所以最小的除数因子从11开始
    int i = 0, j = 0;
    int cnt = 0;
    int unit = 0, tens, hundred = 0;//个十百,tens digit--十进制数,十位数
    for (i = 101; i <= n; i++)
    {
        for (j = 11; j <= sqrt(n); j++)//要有=,因为=sqrt(n)正好是满足完全平方数的情况
        {//j从11开始到sqrt(n)结束,因为当i=n时,n的那个因数可能是sqrt(n)
            if (j * j == i)
            {//符合完全平方数定义,判断下一条件:是否有两位数相同
                unit = i % 10;
                tens = i / 10 % 10;
                hundred = i / 100;
                if ((unit == tens) + (unit == hundred) + (tens == hundred) == 1)//判断是否有两位数相同
                    cnt++;
            }
        }
    }
    return cnt;
}

int main()
{
    int number;
    scanf("%d", &number);
    printf("count=%d\n", search(number));
    return 0;
}

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值