蓝桥杯倒数七天冲刺国一之每日复习第二天

蓝桥杯倒数七天冲刺国一之每日复习第二天,第1张

距离蓝桥杯还有六天!!各位加油!!!不要忘了打印准考证测试环境!

目录

一丶分考场

二丶四平方和

三丶最少砝码

四丶k倍区间


一丶分考场

题目链接:分考场 - 蓝桥云课 (lanqiao.cn)

题目要求:

n 个人参加某项特殊考试。


为了公平,要求任何两个认识的人不能分在同一个考场。


求是少需要分几个考场才能满足条件。


解题思路:

一道dfs题目,首先我们要考虑

直接每个学生去安排,第一个学生分一个考场,然后看第二个 如果认识就开一个新的考场,不认识就放进去,然后我们判断 第i个考场如果满足就把学生放进去,否则就判断下一个考场 如果都认识并且没空考场就一定要开新的考场

我们定义一个g数组 维护考生之间认识与否 g[a][b]=g[b][a]=1代表俩人认识

p数组是用来判断考场第i个考场j位置有没有人

while(p[j][k] && !g[x][p[j][k]])
{
    k++;
}

在一个for里

如果一开始p[j][k]==0,直接退出while,那么说明这个考场还没有人,考生可以坐在这个考场

一开始是p[j][k]==1,然后看g[x][p[j][k]]也就是看j考场中k座位的学生是否与x认识,如果认识那么退出

后边判断 如果P[j][k]为0 把x安排进去 然后回溯

最后当我们for语句执行完了,也就是说所有考场中都有x认识的人,必须为x开辟一个新考场才行

然后就是我们的代码

#include
using namespace std;
int g[101][101],p[101][101];				
int n,m,a,b,num=101;
void dfs(int x,int y)
{ 
	if(y>=num)
	{
		return;					
	}
	if(x>n)
	{
		num = min(num,y);
		return;
	}
	for(int j=1;j<=y;j++)
	{						
		int k=0;
		while(p[j][k] && !g[x][p[j][k]])
		{
			k++;
		}
		if(p[j][k]==0)
		{
			p[j][k]=x;
			dfs(x+1,y);
			p[j][k]=0;
		}
	}                                  		 	  
	p[y+1][0]=x;				
	dfs(x+1,y+1);							
	p[y+1][0]=0;									
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{ 
		cin>>a>>b;
		g[a][b]=g[b][a]=1; 			
	}
	dfs(1,1);
	cout<
二丶四平方和

题目链接:四平方和 - 蓝桥云课 (lanqiao.cn)

题目要求:

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多 4 个正整数的平方和。


如果把 0 包括进去,就正好可以表示为 4 个数的平方和。


比如:

5 = 0^2 + 0^2 + 1^2 + 2^2;

7 = 1^2 + 1^2 + 1^2 + 2^2;

对于一个给定的正整数,可能存在多种平方和的表示法。


要求你对 4 个数排序:

0≤a≤b≤c≤d

并对所有的可能表示法按a,b,c,d 为联合主键升序排列,最后输出第一个表示法。


解题思路:

暴力+稍微优化就可以AC了,如果用4层for循环直接暴力的话肯定G了,那么优化一下。


最后一层for循环是没必要的,因为它可以通过前三次循环来计算出来的,再进行判断是否符合就可以了,并且用x*x<=n/k来控制循环的终止条件可以减少循环次数。


因为a是四个数里最小的,它的最小值是0,最大值是500万除以4;b最小值也是0,因为b是bcd三个数中最小的,所以b的最大值是500万除以3 然后就可以推出c和d的最大值。



 

#include
using namespace std;
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<=n/4;i++)
	{
		for(int j=i;j<=n/3;j++)
		{
			for(int z=j;z<=n/2;z++)
			{
				double num = sqrt(n-i*i-j*j-z*z);
				int sum = sqrt(n-i*i-j*j-z*z);
				if(num==sum)
				{
					cout<
三丶最少砝码

题目链接:最少砝码 - 蓝桥云课 (lanqiao.cn)

题目要求:

你有一架天平。


现在你要设计一套砝码,使得利用这些砝码可以称出任意 小于等于 N 的正整数重量。


那么这套砝码最少需要包含多少个砝码?

注意砝码可以放在天平两边。


解题思路:

这道题可以用动态规划和找规律贪心来做,动态规划有点难了就不写了,这里写出来找规律的做法。


如果当n=1时,只用一个砝码就可以。


当n=2时候,我们要用两个砝码,两个重量为1的砝码即可,但是我们要贪心,我们可以选择更合适的1和3,因为3-1是2,这样范围就变成了1234。


当n=5的时候1 3就不行了,这个时候需要再加入一个砝码,能配合1 3表示5并且能满足贪心的砝码是9,最大的表示范围则是9+3+1=13。


此时我们就找到规律了,1*3=3,3*3=9,可能你觉得三个例子不够规律,那么如果要表达14,3*9=27,27-13=14,可以看得出规律了吧。


#include
using namespace std;
int main()
{             
    int n;
    cin>>n;
    int ans = 1,num = 1,sum = 1; //ans是保存用了几个砝码 num是新的砝码的重量 sum是砝码最高可以表示的值,因为如果n=1只有一种方法我们就初始化为1.
    while(1)
    {
    	if(sum>=n)//如果最高表示的值大于等于n
		{
			break;//跳出循环
		}
		ans++;//砝码+1
		num *= 3;//砝码重量遵循上面的规律
		sum += num;//sum加上新的砝码重量
    }      
    cout<
四丶k倍区间

题目链接:k倍区间 - 蓝桥云课 (lanqiao.cn)

题目要求:

给定一个长度为 N 的数列,A1​,A2​,⋯AN​,如果其中一段连续的子序列 Ai​,Ai​+1,⋯Aj​(i


你能求出数列中总共有多少个 K 倍区间吗?

解题思路:

前缀和 每次相加 然后在数组加上这个k倍的余数

#include
using namespace std;
const int N =100010;
int n,k;
long long s[N],cnt[N];
long long res;
int main()
{
	cnt[0] = 1;
	cin >> n >> k;
	for(int i = 1; i <= n; i ++ )
	{
		cin >> s[i];
		s[i] += s[i - 1];
		res += cnt[s[i] % k];
    	cnt[s[i] % k]++ ;
	}
	cout << res;
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/567610.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)