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;
}
终于搞定了两天的心结了,希望对大家也能有帮助。
感谢您的阅读,欢迎给出建议和指导。