防护伞+深搜选数纠错

okokokok!!!今天终于也是把昨天和前天的习题更改完了,通过不断地调试找到了问题,并进行了纠正,最后测试成功。


有两个习题:1.防护伞  2.选数问题(运用到深搜)

我们先讲第一道的问题,上错误的代码代码:

#include<stdio.h>
#include<math.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	int x[1000];
	int y[1000];
	double dis;
	double max = 0;
	double s[1000];
	int m = 0;
	double min;
	for (int i = 0; i < n; i++)
	{
		scanf("%d%d", &x[i], &y[i]);
	}
	for (int i = 0; i < n; i++)//每次都将其中一个点看做中心
	{
		for (int j = 0; j < n; j++)//求出该点分别到所有点的距离
		{
			dis = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) *( y[i] - y[j]));
			if (dis > max)
				max = dis;
			
		}
		s[m++] = max * max * 3.1415926535;
	}
	 min = s[0];
	for (int i = 1; i < m; i++)
	{
		if (s[i] < min)
			min = s[i];
	}
	printf("%.4lf", min);
	return 0;
}

在我标记的地方,可以看到在错误代码中,我们将max设成全局变量。而max代表的是一个中心点到其他各个点的距离的最大的那一个值,又因为每个点都要设成中心点去得出结果,所以其实max是有几个设为中心点就有几个max。我们将max设为全局变量,就会让第一个中心点得到的max的值留存下来,之后在求第二个中心点的max的时候,其实就不是以中心点为中心到其他点的距离的最大值了,还加入了上一个点的max进行比较,所以出错。

这里我们需要将max设为for循环内部的一个局部变量才是正确的。

以下是正确的代码:

#include<stdio.h>
#include<math.h>
int main()
{
	int n = 0;
	scanf("%d", &n);
	double x[1000];
	double y[1000];
	double dis;
    double max = 0;
	double s[1000];
	int m = 0;
	double min;
	for (int i = 0; i < n; i++)
	{
		scanf("%lf%lf", &x[i], &y[i]);
	}
	for (int i = 0; i < n; i++)//每次都将其中一个点看做中心
	{
		for (int j = 0; j < n; j++)//求出该点分别到所有点的距离
		{
			if (i == j)
				continue;
			dis = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) *( y[i] - y[j]));
			if (dis > max)
				max = dis;//得到最大距离
			
		}
		s[m++] = max * max * 3.1415926535;//把一种情况的伞的面积存入数组s
	}
	 min = s[0];
	for (int i = 1; i < m; i++)//找到最小的面积
	{
		if (s[i] < min)
			min = s[i];
	}
	printf("%.4lf", min);
	return 0;
}


接下来是第2个题,选数:

先贴一份错误代码:

这道题的这个错误代码在输出时,只能得到第一条路线的和,之后的sum都没有存入vc数组中,是什么原因呢?

#include<stdio.h>
int pd[20];
int sum = 0;
int vc[100];//存放每条路径的长度
int m = 0;
int k = 0;//从n个数中任选k个整数
 
void dfs(int x, int arr[], int n,int starts)
{
	
 
	for (int i = starts; i < n; i++)
	{
		if (x == k)//
		{
			vc[m++] = sum;		
 
			return;
		}
 
		if (!pd[i])
		{
			pd[i] = 1;
			sum = sum + arr[i];
			dfs(x + 1, arr, n,i+1);//这里的i+1非常重要,能够达成不降原则
			sum = sum - arr[i];//返回寻找新路径,将返回的节点的值减掉
			pd[i] = 0;//回溯
		}
	}
 
}
 
int main()
{
	int s = 0;//素数的个数
	int n = 0;
	int arr[20];
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	dfs(0, arr, n,0);
	for (int i = 0; i < m; i++)//检测是否为素数
	{
		for (int j = 2; j < vc[i]; j++)
		{
			if (vc[i] % j == 0)
				break;
			if (((j + 1) == vc[i]) && vc[i] % j != 0)
				s++;
		}
	}
	printf("%d", s);
	return 0;
}

我用的输入例子第一行是4 3

大家可以看我下面画出的部分,在调试过程中,我首先发现在x==k的情况下,sum却并没有赋值给vc数组。然后再经过调试,发现在准备求第二个sum,寻找最后一个数的时候 i 已经等于3,再进入下一个dfs后starts就变成了4,而此时 4<4 条件不成立,进不了循环,就无法执行if(x==k)的语句。其实到这里已经很清楚了,我们错误的将if(x==k)这个块放入了for循环中,导致无法在寻找到最后一个值的时候进行判断,将正确答案放入vc数组并返回。

我们只需将我画出的这个部分,放到目前所在的for循环的外面,就可以解决了

下面贴上修改后的正确代码:

#include<stdio.h>
int pd[20];
int sum = 0;
int vc[100];//存放每条路径的长度
int m = 0;
int k = 0;//从n个数中任选k个整数

void dfs(int x, int arr[], int n,int starts)
{

	
		if (x == k)//
		{
			vc[m++] = sum;		

			return;
		}
		for (int i = starts; i < n; i++)
	
		{
			if (!pd[i])
			{
				pd[i] = 1;
				sum = sum + arr[i];
				dfs(x + 1, arr, n,i+1);//这里的i+1非常重要,能够达成不降原则
				sum = sum - arr[i];//返回寻找新路径,将返回的节点的值减掉
				pd[i] = 0;//回溯
			}
		}
}

int main()
{
	int s = 0;//素数的个数
	int n = 0;
	int arr[20];
	int j = 0;
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	dfs(0, arr, n,0);
	for (int i = 0; i < m; i++)//检测是否为素数
	{
		for ( j = 2; j <= vc[i]; j++)
		{
			if (vc[i] % j == 0)
				break;
			/*if (((j + 1) == vc[i]) && vc[i] % j != 0)
				s++;*/
		}
		if (vc[i] == j)
			s++;
	}
	printf("%d", s);
	return 0;
}

终于搞定了两天的心结了,希望对大家也能有帮助。

感谢您的阅读,欢迎给出建议和指导。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值