首页 > 其他分享 >PTA-第三次机考题解

PTA-第三次机考题解

时间:2023-12-09 14:11:05浏览次数:41  
标签:第三次 int str2 sum mid PTA ++ 考题 模版

PTA-第三次机考题解

7-1 玩游戏一

典型的二分模版题,之前发的第十一次练习题目中对二分有详细的讲解,这道题就是二分的第二种模版,原封不动。相信认真看过的同学还是有思路的。嘿嘿!

给没有看过的同学下面再讲一次二分:

直接讲整数二分,浮点数二分只需要修改细节就好(直接讲两种模版,所有的二分都是这种模版)

1.

img

每次找到区间的中点,将s[mid]与x的值相比较。如果是图中的这种情况,x>s[mid] ,所以x存在于右区间。那么调整区间,将区间的左端点调整为mid+1(为什么是mid+1后面会讲),再去循环处理右区间。另一种情况同理。

2.

因为存在边界问题,所以这里的二分需要分情况讨论,对应的代码也有两种。

首先是边界调整的问题。重要的就是那边可以取到最后的值x,就将哪边的边界调整为mid。直接看代码讲。(代码题目是找到x在数组中的位置)

先看第一种:

int l = 0,r = n-1//设置左右端点
while(l<r)
{
	int mid = l+r>>1;//设置中点
	if(s[mid]>=x) r = mid;
    //注意此时x可以在这个判断条件中取到,所以这个条件对应的边界调整为mid
	else l = mid+1;
    //另一个对应的调整为mid+1或mid-1;
}

第二种:

int l = 0,r = n-1;
while(l<r)
{
	int mid = l+r+1>>1;
	if(s[mid]<=x) l = mid;
    //这时x可以在新的条件中取到,所以对应边界调整为mid,其余同理。
	else r = mid-1;
}

3.

另外的,两种情况所移动的方向不同。

当用第一种模版时,将会从数组左向右去找x的值,直到从左向右找到第一个数为止,此时的边界l就是第一个x的位置。

当用第二种模版时,将会从右向左,直到找到一个数为止,l代表找到的第一个x的位置,注意使用这个模版时,mid = l+r+1>>1。

以上就是二分的两种模版。

那么对于这道题,要求的是求每个战士可以补充能量的最大值,那么可以设置最少的能量值是0,最大的能量值是数组当中最大的元素(每个战士获得的能量不可能超过这个max)。

那就得到了l和r的初始值,

int l = 0, r = max;

然后就是套用模版,

在模版的选择上,因为满足条件的值总在左端取到,所以选择第二种模版。

while (l < r)
{
	int mid = l+r+1 >> 1;//注意此时mid = (l+r+1)/2;
	if (check(mid)) l = mid;//如果满足条件,说明此时每个战士能量值太小了,就将左边界调整为mid
	else r = mid-1;//同理将右边界调整为mid-1
}

下面是check(int x) 函数,作用是用来判断是否每个战士都可以得到能量值x,如果可以就返回true,否则就返回false;

//check函数
//就是判断每个a[i]中含有几个x,将个数相加,看和战士数(m)的大小
//如果个数大于m,说明这个能量值是满足条件的,就返回true,否则就返回false
bool check(int x)
{
	int sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += a[i] / x;
	}
	if (sum >= m) return true;
	else return false;
}

以下是完整代码:

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
int a[10010];
int n, m;
bool check(int x)
{
	int sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += a[i] / x;
	}
	if (sum >= m) return true;
	else return false;
}
int main()
{
	scanf("%d %d", &n, &m);
	int max = -2e9;
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &a[i]);
		max = a[i] > max ? a[i] : max;
	}
	int l = 0, r = max;
	while (l < r)
	{
		int mid = l+r+1 >> 1;
		if (check(mid)) l = mid;
		else r = mid-1;
	}
	printf("%d\n", l);
	return 0;
}

6-4 字符串重组

想问没过的同学们,你们新字符串后面+‘\0’了么,最后使用%s输出的哦,不然就会烫烫烫了。/ww

下面看题:

首先我们定义一个数组s用来储存拼接之后的字符串,另外设置指针k指向s数组,指针m指向str1数组。

 char s[128];//储存新字符串
 int k = 0,m = 0;

我们用循环来遍历一遍str2数组

用x储存str2[i]表示的数,然后将st1中的x个字符储存到新字符数组中,最后将str2[i]储存到新数组中。

for (int i = 0;str2[i]!='\0'; i++)//如果str2[i] == '\0'说明字符串结束,结束循环
    {
        int x = str2[i] - '0';//储存str2[i]表示的数
        for (int j = 0;j<x; j++)
        {
            s[k++] = str1[m++];//将st1中的x个字符储存到新字符数组
        }
        s[k++] = str2[i];//最后将str2[i]储存到新数组中
    }

然后考虑一种情况,如果str2循环完毕,但是str1还没有循环完毕。

这时我们需要把str1剩余的字符储存到新字符串中。

  while (str1[m]!='\0') s[k++] = str1[m++];

最后将新数组储存会原数组就好。

 for (int i = 0; i < k; i++)
    {
       str1[i] = s[i];
    }

注意注意注意:+++++++'\0'

我真的哭死,不加'\0'就会输出乱码,当时卡我好久。

因为最后输出时,主函数使用的是%s,所以我们必须加一个'\0'表示字符串结束。

 str1[k] = '\0';

以下是完整代码:

void recombination(char str1[], char str2[])
{
    char s[128];
    int k = 0,m = 0;
    for (int i = 0;str2[i]!='\0'; i++)
    {
        int x = str2[i] - '0';
        for (int j = 0;j<x; j++)
        {
            s[k++] = str1[m++];
        }
        s[k++] = str2[i];
    }
    while (str1[m]!='\0') s[k++] = str1[m++];

    for (int i = 0; i < k; i++)
    {
       str1[i] = s[i];
    }
    str1[k] = '\0';
}

6-2 麦卡锡函数

这道题的递归方式,题目中已经给出,我们只需要注意输出方式就好了。

int m91(int n)
{
	printf("%d ", n);//先把当前的n输出
	if (n > 100) //按照题意递归
	{
		return n - 10;
	}
	else 
	{
		return m91(m91(n + 11));
	}
}

6-1 数组逆序

将第一个数与倒数第一个数交换,第二个数与倒数第二个数交换.......以此类推。

void reverseArray(int array[], int size)
{
	for (int i = 0; i < size / 2; i++)
	{
		int x = array[i];
		array[i] = array[size - 1 - i];
		array[size - 1 - i] = x;
	}
}

6-3 矩阵校验

懒了。。。。。直接解释一下官方的代码。

void check(int matrix[][LEN], int sum_row[], int sum_col[], int rows, int cols)
{
	int err_i = -1, err_j = -1;//err_i储存错误数据的行数,err_j同理
	for (int i = 0; i < rows; ++i) 
	{
		int sum = 0;
        //计算每一行的和
		for (int j = 0; j < cols; ++j)
		{
			sum += matrix[i][j];
		}
        //判断是否与输入值相等
		if (sum != sum_row[i])
		{
			err_i = i;
		}
	}
	for (int i = 0; i < rows; ++i)
	{
		int sum = 0;
		for (int j = 0; j < cols; ++j) 
		{
			sum += matrix[j][i];
		}
		if (sum != sum_col[i]) 
		{
			err_j = i;
		}
	}
}

完结!

标签:第三次,int,str2,sum,mid,PTA,++,考题,模版
From: https://www.cnblogs.com/csclixuan/p/17890881.html

相关文章

  • PTA-2023第十二次练习题目题解
    PTA-2023第十二次练习题目题解(祝大家机考顺利)以下代码已做防抄袭处理,切勿抄袭。注意:手机端因为屏幕限制,代码会有(不希望的)换行。解决方案:1.建议使用电脑端打开。2.点击代码进入全屏观看。6-24实验8_3_设计函数利用冒泡排序的思想,将每一列的最小值放到每列的最后一个位置。voi......
  • PTA7、8、期末考试总结
    PTA7、8、期末考试总结写在前面:此次的7、8两次PTA作业总体难度没有之前难,主要考察的是哈希表以及动态数组的运用,只要肯研究,肯学习就可以写的可以。PTA总结:7-1容器-HashMap-检索分数10全屏浏览题目切换布局作者 蔡轲单位 南昌航空大学输入多......
  • PTA第三次总结
    这次是对PTA第七次和第八次的总结,经过上次菜单5次迭代后我对类的设计更加深刻,而这次面对课程成绩统计的迭代二,由于迭代一我还是面向过程写的,多以毫不犹豫我重构了类图,但由于个人原因不小心误删了,所以没有类图展示(,重构代码后只剩两个测试点过不了,因为没有给测试点所以只能结束后取......
  • BLOG-3 PTA总结
    此次博客主要是针对课程成绩统计程序类题目和期末题目的总结前言:随着对Java学习的深入,我接触到了Java中更深层的知识:扩展、多态和接口。这些内容的学习更加困难,但其主要目的也是利于代码的维护和修改,学会了这些将会使我们更加靠近现实的编写环境。课程成绩统计程序-2课程成绩统......
  • PTA题目集7~8+期末总结
    目录:1.前言2.设计与分析3.BUG与修正4.缺陷与改进5.总结一、前言题目集7的成绩统计2有57个人获得了满分,相较于成绩统计1的31人满分有很大的进步。我认为主要的原因是在成绩统计1发布时间较早,很多同学都是在最后才来写PTA的作业......
  • 第三次博客
    第三次博客前言知识点本次实验最关键的就是课程成绩统计程序,两次实验根据课程成绩统计程序-1一点一点添加功能,难度逐级递增,主要知识点还是与java类有关,其中包括了:方法:类中定义的行为,用于描述对象能够做什么。方法包括普通方法、构造方法和静态方法等。封装:通过访问修饰符(public、p......
  • linux iptables操作
    1.查看iptables规则iptables-nL2.添加iptables规则iptables-AINPUT-s10.0.0.0/8-d10.0.0.0/8-ptcp-mmultiport--dports6379,6643-jACCEPT该命令使用 -AINPUT 将规则添加到过滤器的INPUT链(即入站流量),并指定以下条件:-s10.0.0.0/8:源IP地址是 10.0.0.......
  • pta总结blog3
    前言第七次题目集:该次题目集有四道题目,有两道是考察的HashMap的检索与排序功能,一道是考察的多态的运用,最重要的一道便是成绩计算系统-2,第六次题集的成绩计算系统的升级版,该题在前一个系统的基础之上增加了一种课程类型:实验,也增加了对应的考核方式。第八次题目集:该次题目集共有五......
  • 21207119-第三次java博客
    前言第三次博客,主要是成绩系统和期末考试题量:不是太大,小题写的会快些,但是系列题找测试点的过程有时候很费时间难度:中等偏上,包含了诸多细节和需求,包括各种异常处理和特殊情况的处理测试与分析7-1容器-HashMap-检索分数10全屏浏览题目切换布局作者 蔡......
  • PTA7-8次PTA题目集以及期末考试总结
    PTA7-8次PTA题目集以及期末考试总结一、前言:本次博客介绍PTA第七次和第八次作业以及期末考试的总结。第七次题目有涉及到容器HashMap的检索与排序,其中还有特殊的HashMap来存储内容,同时还有多态的使用与学习,可以让你对多态有进一步的了解,对于......