IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 用C语言实现PTA B题(1001——1009) -> 正文阅读

[C++知识库]用C语言实现PTA B题(1001——1009)

前言

有一说一,用C语言刷题并不是一件很令人愉快的事。

拿代码实现很难,相关的题解也很少,即使找到了题解,也很容易是错误的。

但因为我自己想走的大方向是偏向底层的物联网,再加上我的python和C++还没学完,因此拿C语言修炼内功就变成了刚需

不过我依旧认为C语言很重要,是其他一切语言的基础。

目前我快要学完python了,过两天开始用python和C++刷题后,我也会时不时的回归一下C语言。


提示:

第九题我只研究出了使部分测试点通过的代码,有会的大神可以在评论区中把代码亮出来,欢迎一起讨论

1001:

对给定的任一不超过 1000 的正整数?n,简单地数一下,需要多少步(砍几下)才能得到?n=1?

#include <stdio.h>
int main()
{
	int n, count = 0;
	scanf("%d", &n);
	while (n != 1) 
	{
		switch (n % 2)
		{
		case 0:
			n = n / 2;
			count++;
			break;
		case 1:
			n = (3 * n + 1) / 2;
			count++;
			break;
		default:
			break;
		}
	}
	printf("%d", count);
	return 0;
}

求2的余数,三种情况在switch....case语句中进行分别讨论

讨论的情形可以通过读题得知:?对任何一个正整数?n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把?(3n+1)?砍掉一半。这样一直反复砍下去,最后一定在某一步得到?n=1。

把这句话转化为数学公式即可

1002:

读入一个正整数?n,计算其各位数字之和,用汉语拼音写出和的每一位数字

这道题可以用switch..case语句列出汉语拼音的每种读法,不过。。有些不太美观。

我用的是二维数组的方法,可以看程序中的注释

#include <stdio.h>
#include <stdlib.h>//储存排序和查找程序的头文件
#include <string.h>

int main() {
	char num[102];
	int put[20];
	int sum = 0, i = 0, lenth = 0, k = 0;
	char pin[10][5] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };//用二维数组的第一维储存汉语拼音
	scanf("%s", &num);//把字符串按照字符形式存储到num数组中
	while (num[i] != '\0') {
		sum += num[i++] - '0';//把字符形式的数字依次相加
	}
	while (sum > 0) {
		put[k++] = sum % 10;//这段程序是为了把数字转化为三位数
		sum = sum / 10;
		lenth++;//计算汉语拼音一共需要打印的长度
	}
	for (i = lenth - 1; i >= 0; i--) {//数组从0开始计数
		printf("%s", pin[put[i]]);//用二维数组的第二维储存put[k++]
		if (i != 0) {
			printf(" ");//顺便加上空格,以免格式错误
		}
	}
	return 0;
}

还有,不要把多维数组妖魔化

比如说二维数组,其实就是一维数组的一维数组 ,数组套数组。

1003:

答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

  1. 字符串中必须仅有?P、?A、?T这三种字符,不可以包含其它字符;
  2. 任意形如?xPATx?的字符串都可以获得“答案正确”,其中?x?或者是空字符串,或者是仅由字母?A?组成的字符串;
  3. 如果?aPbTc?是正确的,那么?aPbATca?也是正确的,其中?a、?b、?c?均或者是空字符串,或者是仅由字母?A?组成的字符串。

现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

这道题主要考的就是找规律,规律一和规律二是规律三的子集

AAPAATAAA是正确的,但是AAAPAATAA就不对了,也就是说,

前面的字符串必须比后面的字符串少一个A;

中间的A个数乘以开始的字符串个数=后面的字符串个数。

因此可以依据P,T,A三个字母进行字符串的分割,用二维数组,第一维存储字符个数,第二维存储字符,并进行条件判断。例如有一个A应该怎么做,依次类推。

代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
	int n;
	scanf("%d", &n);
	getchar();
	char recode[n][200];
	int i, j;
	for (i = 0; i < n; i++)
	{
		scanf("%s", recode[i]);
		getchar();
	}

	for (i = 0; i < n; i++)
	{
		int flagt = 0, flagp = 0, flaga = 0, flag = 0;
		int nump = 0, numt = 0, num = 0;
		for (j = 0; flag == 0 && recode[i][j] != '\0'; j++)
		{
			if (recode[i][j] != 'P' && recode[i][j] != 'A' && recode[i][j] != 'T')
			{
				flag = 1;
				break;
			}
			else if (recode[i][j] == 'P')
			{
				flagp++;

			}
			else if (recode[i][j] == 'T')
			{
				flagt++;
			}
			else if (flagp > 1 || flagt > 1)
			{
				flag = 1;
				break;
			}
			else if (flagp == 0 && flagt == 0 && recode[i][j] == 'A')
			{
				nump++;
			}
			else if (flagp != 0 && flagt == 0 && recode[i][j] == 'A')
			{
				numt++;
			}
			if (recode[i][j] == 'A')
			{
				num++;
			}
		}
		if (flag != 0 || num == 0 || flagp == 0 || flagt == 0)
		{
			printf("NO\n");
		}
		else if (nump * numt == (num - nump - numt))
		{
			printf("YES\n");
		}
		else printf("NO\n");

	}
	return 0;
}

1004:

读入?n(>0)名学生的姓名、学号、成绩,分别输出成绩最高和成绩最低学生的姓名和学号

这道题可以题用结构体储存学生的信息,表示出成绩后进行大小比较。

其实看似复杂的题,都是用一个个简单程序叠加起来的,我们需要的是化繁为简的能力,以及。。。一定的数学基础,能自己尝试写代码的勇气,还有一遍遍查找bug的毅力。

#include <stdio.h>
#include <stdlib.h>
struct student {
	char name[11];
	char id[11];
	int score;
}temp, ans_max, ans_min;
int main()
{
	int n;
	ans_min.score = 101, ans_max.score = -1;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%s%s%d", &temp.name, &temp.id, &temp.score);
		if (temp.score < ans_min.score) {
			ans_min = temp;
		}
		if(temp.score>ans_max.score){
			ans_max = temp;
		}
	}
	printf("%s %s\n", ans_max.name, ans_max.id);
	printf("%s %s\n", ans_min.name, ans_min.id);
	return 0;


}

(其实这道题用python很好做,可惜我当时不太会)

1005:

现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。

?这道题写起来稍微有点绕,不过思路很清晰

输入元素遍历一遍,求猜想数时遍历一遍,判断关键数字时倒着再来一遍

#include <stdio.h>

int main()

{

	int K = 0, n = 0;

	int tabel[101] = { 0 };

	scanf("%d", &K);

	//将元素对应位置标记为1 

	for (int i = 0; i < K; i++)

	{

		scanf("%d", &n);

		tabel[n] = 1;

	}

	//遍历数组,求还存在数的猜想数 

	for (int i = 1; i <= 100; i++)

	{

		if (tabel[i])

		{

			for (n = i; n > 1; )

			{

				if (n % 2)

				{

					n = (3 * n + 1) / 2;

				}

				else

				{

					n /= 2;

				}

				//检验猜想数是否存在,需考虑猜想数超出100,数组越界的问题 

				if (n <= 100 && tabel[n])

				{

					tabel[n] = 0;

					K--;

				}

			}

		}

	}

	for (int i = 100; i >= 1; i--)

	{

		if (tabel[i] == 1)

		{

			printf("%d%c", i, --K ? ' ' : '\0');

		}

	}
	return 0;
}

1006:

让我们用字母?B?来表示“百”、字母?S?表示“十”,用?12...n?来表示不为零的个位数字?n(<10),换个格式来输出任一个不超过 3 位的正整数。例如?234?应该被输出为?BBSSS1234,因为它有 2 个“百”、3 个“十”、以及个位的 4。

这道题比较简单,把C语言基础题:如何表示一个三位数弄会就行,然后用for循环输出字符和数字

如没有编译出来,可以看我C语言专栏里的前几篇文章,进行一下基础的回顾

#include <stdio.h>
int main()
{
	int b=0, s=0, n=0, B,S,number,i;
	scanf("%d", &number);
    b=number/100;
	s = number / 10 % 10;
	n= number%10;
	for (i = 1; i <= b; i++)
	{
		printf("B");
	}
	for (i = 1; i <= s; i++)
	{
		printf("S");
	}
	for (i = 1; i <= n; i++)
	{
		printf("%d",i);
	}
	printf("\n");
	return 0;
}

1007:?

让我们定义dn?为:dn?=pn+1??pn?,其中pi?是第i个素数。显然有d1?=1,且对于n>1有dn?是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N(<105),请计算不超过N的满足猜想的素数对的个数。

?这又是一道比较难的题,我当时做的时候做成了素数,后来才发现差的很远,这道题卡了我好几天。

#include<stdio.h>
#include<math.h>
int main()
{
	int i, j, k, temp, n = 0;
	int s = 2;
	scanf("%d", &k);
	if (k == 1) return 0;
	else
		for (i = 2; i <= k; i++)
		{
			temp = sqrt(i);
			for (j = 2; j <= temp; ++j)
				if (i % j == 0) break;
			if (j >= temp + 1)
			{
				if ((i - s) == 2)
					n++;
				s = i;
			}
		}
	printf("%d", n);
	return 0;
}

附一下我当时写的注释:

//一定要写返回值!此题用数组!
//这样才是正确的!!!int p[100];int p[100]=0是错的!!!
//它不是在求素数,是在求除过之后是素数的数!!!!!
//你得先判断是不是素数,然后判断相邻的两个素数是否相差2!!

?这是我当时写的运行部分正确的代码:

#include <stdio.h>
int main()
{
	int N, i,j,m=0,h=0;
	int prime;
	int p[1000];
	scanf("%d", &N);
	for (i = 2; i < N; i++) {
		prime = 1;
		for (j = 2; j < i; j++)
		{
			if (i % j == 0)
			{
				prime = 0;
				break;
			}
		}
		if(prime)
		{
			p[m] = i;			
			if (m>=1&&p[m] - p[m-1] == 2) 
				h++;
			m++;
		}
	}		
	printf("%d", h);
	return 0;
}

1008:

一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A0?A1??AN?1?)变换为(AN?M??AN?1?A0?A1??AN?M?1?)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法??

?可以先输出5,6,后输出1,2,3,4,注意把循环的位数数准了就可以

#include <stdio.h>
int main()
{
	int m, n, a[1000], i;
	int count = 0;
	scanf("%d %d", &m, &n);//是格式问题!!!!
	for (i = 0; i < m; i++)
		scanf("%d", &a[i]);
	n = n % m;//计算需要右移的位数
	for (i = m - n; i < m; i++) {
		printf("%d", a[i]);//输出m-n到m-1号
		count++;
		if (count < m)
			printf(" ");//如果已经输出的个数小于m,则要输出空格
	}
	for (i = 0; i < m - n; i++) {
		printf("%d", a[i]);
		count++;
		if (count < m)
			printf(" ");
	}
	return 0;
}

另一种方式使用队列(先进先出)来实现,这对C语言不太友好,毕竟队列还要自己写

#define MAX 102
#include <stdio.h>
int Divisor(int x, int y) {
	if (!(y % x))
		return x;
	return Divisor(y % x, x);
}

int main() {
	int a[MAX] = { 0 };
	int num, step;
	scanf("%d %d", &num, &step);

	for (int i = 1; i <= num; i++) {
		scanf("%d", &a[i]);
	}

	step = step % num;

	int loop = Divisor(num, step);

	for (int i = 1; i <= loop; i++) {
		int temp = i, p;
		int last_p = a[temp];
		do {
			temp = (temp + step) % num;
			if (!temp)
				temp = num;

			p = a[temp];  //取出下一个
			a[temp] = last_p; //存入上一个

			last_p = p;
		} while (temp != i);
	}

	for (int i = 1; i <= num - 1; i++) {
		printf("%d ", a[i]);
	}
	printf("%d\n", a[num]);

	return 0;
}

1009:

给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

这个不知道为什么,不是部分正确就是编译错误,我自己也很懵

部分正确的代码:

#include <stdio.h>
#include <string.h>
int main()
{
    char str[100];
    scanf("%s", str);
    int len = strlen(str), r = 0, h = 0, i;
    char ans[100][100];
    for (i = 0; i < len; i++) {
        if (str[i] != ' ')
            ans[r][h++] = str[i];
        else {
            ans[r][h] = '\0';
            r++;
            h = 0;
        }
    }
    for (i = r; i >= 0; i--) {
        printf("%s", ans[i]);
        if (i > 0)
            printf(" ");
    }
    return 0;
}

编译错误的代码:

#include <stdio.h>
#include <string.h>
int gaibian(char* str, int ans[100][100])
{
    int len = strlen(str), r = 0, h = 0, i;
    for (i = 0; i < len; i++) {
        if (str[i] != ' ')
            ans[r][h++] = str[i];
        else {
            ans[r][h] = '\0';
            r++;
            h = 0;
        }
    }
}
int main()
{
    char* str;
    int ans[100][100];
    scanf("%s", str);
    int len = strlen(str), r = 0, h = 0, i;
    for (i = r; i >= 0; i--) {
        gaibian(*str, ans[100][100])
            printf("%s", ans[i]);
        if (i > 0)
            printf(" ");
    }
    return 0;
}

欢迎大家的讨论,批评,指正。?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:27:16  更:2021-07-29 11:29:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 9:55:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码