第七次训练课总结

最后更新于 2025-08-02 21:26:30
作者
分类 个人记录

题目:B3957 [GESP202403 三级] 完全平方数

错误原因

思路不正确,我的思路是枚举a[i]和a[j]暴力枚举看这个数的平方是否正好等于a[i]与a[j]的和

思路

首先题目要我们输出共有几组和是完全平方数的a[i],a[j]

按照题意输入后枚举a[i]与a[j]为了不重复,j从i+1开始枚举。我们知道每个数都能开根,但是有的是小数,有的是正整数。所以将a[i]与a[j]的和开根后强转成int类型,如果强转后仍是整数再乘一个a[i]与a[j]开根后的数应该与a[i]与a[j]的和相同,所以按照上述条件判断后如果符合就答案加1

最终输出cnt即可

重难点

如何判断开根后的a[i]与a[j]是否为正整数

思路

#include <bits/stdc++.h>
using namespace std;

int a[1005];

int main()
{
	int n,cnt=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];//输入
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)//为避免重复,从i+1开始枚举起
		{
			if(int(sqrt(a[i]+a[j]))*int(sqrt(a[i]+a[j]))==a[i]+a[j])//强转a[i]与a[j]的和为int类型,并判断两个开根后的sqrt(a[i]+a[j])相乘是否和就是a[i]+a[j]
            {
                cnt++;
            }
		}
	}
	cout<<cnt;//输出最终答案
	return 0;
}

题目:P2689 东南西北

错误原因

在计算距离时没有用abs来计算,因为x1、x2和y1、y2的和谁大谁小题目没说,所以还要加上abs函数;并且将横轴与纵轴弄反了

思路

题目要我们计算,如果能到达点位,就输出最少移动次数,否则输出-1

输入完x1,y1,x2,y2以及a数组后可以算出总共要移动的距离(完整式子是abs(x2-x1)+abs(y2-y1)),这样方便后续操作

遍历a数组,此时a[i]中的数有四种可能:东(E)南(S)西(W)北(N)。当a[i]是N时,只有当y2在y1的上面时,走过去才不会走回头路。同样的道理,如果a[i]是S,y2必须在y1的下面。如果a[i]是E,x2必须在x1的右边。如果a[i]是W,x2必须在x1的左边。在每一个判断里,都将x1和y1调整为现在所在的行和列,距离缩短了1,所以减1,移动步数加1。这里还要特判,如果距离为0了,就要break

然后再次判断距离是否为0,是则输出移动步数,否则就还没到达指定点,输出-1

重难点

1.判断现在现在是否到达点上了

2.计算出起始点与终止点的距离

代码

#include <bits/stdc++.h>
using namespace std;

char a[55];

int main()
{
	int x1,y1,x2,y2,n,cnt=0;
	cin>>x1>>y1>>x2>>y2;
	int jl=abs(x2-x1)+abs(y2-y1);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		if(a[i]=='N' && y2>y1)//当a[i]是N时,y2要在y1的上边
		{
            y1--;//向上移动了,所以要减1
            cnt++;
            jl--;
		}
		else if(a[i]=='S' && y2<y1)//当a[i]是S时,y2要在y1的下边
		{
            y1++;//向下移动了,所以要加1
            cnt++;
            jl--;
		}
		else if(a[i]=='E' && x2>x1)//当a[i]是E时,y2要在y1的右边
		{
			x1++;//向右移动了,所以要加1
            cnt++;
            jl--;
		}
		else if(a[i]=='W' && x2<x1)//当a[i]是W时,y2要在y1的左边
		{
			x1--;//向左移动了,所以要减1
            cnt++;
            jl--;
		}
        if(jl==0)//已经到达点上了
        {
            break;
        }
	}
	if(jl==0)//能到达指定点
	{
		cout<<cnt;
	}
	else//不能到达指定点
	{
		cout<<"-1";
	}
	return 0;
}

题目:P5594 【XR-4】模拟赛

错误原因

没读懂题,所以尝试骗分但是没骗到

思路

题目要我们输出每天教练要设几场模拟赛

首先我们做一个二维桶数组,在每次输入这个同学的分数后,我们都要统计这场比赛是否有人参加,即t[a][j]++,然后循环k次,用ans来记录要设几场比赛,此时再遍历每个同学的能参赛的那几天,如果大于0,就说明他今天能参赛,所以ans加1,最后输出ans和一个空格

重难点

用桶数组来统计每一位同学的参赛情况

代码

#include <bits/stdc++.h>
using namespace std;

int t[1005][1005];

int main()
{
	int n,m,k,a;
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a;
            t[a][j]++;//说明这天有人可以参赛,标记一下
		}
	}
	for(int i=1;i<=k;i++)
    {
        int ans=0;//用来存今天要设的比赛场数
        for(int j=1;j<=m;j++)
        {
            if(t[i][j]>0)//说明有人要参加这一套题
            {
                ans++;
            }
        }
        cout<<ans<<" ";
    }
	return 0;
}

题目:P12176 [蓝桥杯 2025 省 Python B] 书架还原

错误原因

思路错了,我的思路是当a[i]比a[i+1]大时,就交换两个数

思路

这道题是要我们求出最少交换次数

首先先输入a[i],即这本书的编号,同时再来记录现在a[i]的书架编号

遍历w数组,如果书架编号与i不相等,说明我们要调整,所以先将正确的书架编号调整过来,然后将书架上的数进行调换,当然啦,移动次数也要加1

输出移动次数

重难点

想到用另一个数组来存储书架编号

代码

#include <bits/stdc++.h>
using namespace std;

int a[1000005],w[1000005];

int main()
{
	int n,cnt=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
        cin>>a[i];
        w[a[i]]=i;//用w数组来存这本书的书架编号
	}
	for(int i=1;i<=n;i++)
	{
        if(w[i]!=i)//与正确的不符
        {
            w[a[i]]=w[i];//调整书架编号
            swap(a[w[i]],a[i]);//交换书架上的书
            cnt++;
        }
	}
	cout<<cnt;
	return 0;
}