蓝桥杯 四平方和 数的分解(简单dfs,算法时间复杂度优化)

这篇博客探讨了两个编程问题:一是如何找到四个非负整数,使得它们的平方和等于给定正整数;二是如何计算不包含2或4的数位的三个数的组合数量。文章通过两种不同的深度优先搜索(DFS)算法解决了四平方和问题,并提供了使用for循环和递推方法解决数的分解问题的示例代码。优化后的DFS算法显著提高了性能,满足了资源约束。此外,还展示了如何通过for循环和递推形式来计算特定数位条件的数的组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

四平方和

程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开

例如,输入:
5
则程序应该输出:
0 0 1 2

再例如,输入:
12
则程序应该输出:
0 2 2 2

再例如,输入:
773535
则程序应该输出:
1 1 267 838

资源约定:
峰值内存消耗 < 256M
CPU消耗 < 3000ms

题解:

错误dfs:
如下:num为1是一重循环,num>4结束,共有四重循环。

void dfs(int x,int num,int st)
{
	if(flag==false)
	{
		cout<<x<<" "<<num<<endl;
		int sqr=(int)sqrt(1.0*x); 
		if(x<0) return;
		if(num>4 && x!=0) return;
		if(x==0 && num>4)
		{
			for(int i=0;i<re.size();i++) cout<<re[i]<<" ";	
			flag=true;	
			return;
		}
		
		for(int i=st;i<=sqr;i++)
		{
			re.push_back(i);
			dfs(x-i*i,num+1,i);
			re.pop_back();	
		}
	}
}

正确dfs:
优化为3重循环,第四重循环优化为判断剩余的数能否表示为一个整数的平方。
判断方式:double sqr=sqrt(1.0*x);sqr==(int)sqr?

#include<bits/stdc++.h>
using namespace std;
vector<int> re;
bool flag=false;
//num为1第一重循环,共有3重循环(num可为1,2,3),到num==4时结束 
void dfs_2(int x,int num,int st)
{
	if(flag==false)
	{
		if(x<=0) return;
		double sqr=sqrt(1.0*x); 
		if(num==4)
		{
			if(sqr==(int)sqr && (int)sqr>=st) 
			{
				re.push_back((int)sqr);
				for(int i=0;i<re.size();i++) cout<<re[i]<<" ";
				re.pop_back();
				flag=true;
				return;
			}
			else
			{
				return;
			}
		} 
		for(int i=st;i<(int)(sqr+0.5);i++)
		{
			re.push_back(i);
			dfs_2(x-i*i,num+1,i);
			re.pop_back();
		}
	}
}
int main()
{
	int num;
	int startime, endtime;
	cin>>num;
	startime = clock();
	dfs_2(num,1,0);
	endtime = clock();
	cout<<endl<<"时间为"<<(double)(endtime-startime) / CLOCKS_PER_SEC;
}

数的分解

在这里插入图片描述

题解

for循环形式:

#include<bits/stdc++.h>
using namespace std;
int ans=0;
vector<int> vi;
bool check(int num)
{
	while(num!=0)
	{
		if(num%10==2 || num%10==4) return true;
		num/=10;
	}
	return false;
}
int main()
{
	int ans=0;
	for(int i=1;i<2019;i++) 
	{
		if(check(i)==true) continue;
		for(int j=i+1;j<2019-i;j++)
		{
			if(check(j)==true) continue;
			int k=2019-i-j;
			if(k>j && check(k)==false)
			{
				ans++;
			}
		}
	}
	cout<<ans;
} 

递推形式:

#include<bits/stdc++.h>
using namespace std;
int ans=0;
vector<int> vi;
bool check(int num)
{
	while(num!=0)
	{
		if(num%10==2 || num%10==4) return true;
		num/=10;
	}
	return false;
}
void dfs(int x,int num,int st)
{
	if(x<0) return;
	if(num==3)
	{
		if(check(x)==false && x>st)
		{
			//vi.push_back(x);
			//for(int i=0;i<vi.size();i++) cout<<vi[i]<<" ";
			//cout<<endl;
			//vi.pop_back();
			ans++;
			return;
		}
		else
		{
			return;
		}
	}	
	for(int i=st+1;i<x;i++)
	{
		if(check(i)==true) continue;
		//vi.push_back(i);
		dfs(x-i,num+1,i);
		//vi.pop_back();
	}
}
int main()
{
	dfs(2019,1,0);
	cout<<ans; 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值