每日刷题(九)
方阵(结果填空题)
需要求出有多少对小朋友可以互相看见
思路确实很难想,我们可以把抽象的东西具体化,把每个小朋友看作是一个点,这里编程肯定需要用到多次循环。不妨先从左上角第一个点出发,依次遍历,但是最后一列和最后一行都不要遍历。为什么?请继续看
首先,我们先求出行与行之间,列与列之间相邻的情况。
首先定义变量sum = 0;这里我用变量sum来记录小朋友的对数。从行或者列的角度出发,sum = (n - 1)*n。那么行与列的总和便是sum += (n - 1) n2;
接下来我们考虑对角的情况。
从行或者列的角度出发,sum += (n - 1) * (n - 1) ,那么行与列的总和便是sum += (n - 1) n2
最后考虑一般情况
即i / j != 1 && i * i + j * j <= k * k
详细的C语言代码如下:
#include<stdio.h>
int main()
{
int n = 1000, k = 500, sum = 0, i, j, x, y;
/*首先考虑相邻情况*/
sum += (n - 1) * n * 2;
/*再考虑对角情况*/
sum += (n - 1) * (n - 1) * 2;
/*最后考虑一般情况*/
for(x = 0; x <= n - 2; x++)
for(y = 0; y <= n - 2; y++) //遍历除了最右边一列的所有点
for(i = 1; i <= n - 1 - y; i++) //宽度
for(j = 1; j <= n - 1 - x; j++) //长度
{
if(i / j != 1 && i * i + j * j <= k * k)
{
sum++;
sum %= 1000000007;
printf("%d\n",sum);
}
}
printf("共有%d对小朋友可以互相看见\n",sum);
return 0;
}
运行结果如下:
很明显,这个结果一时半会运行不出来,反正我运行了一下午都没出来
所以我们得换条路走,我一直在想,既然四个循环数据量太大,那么我缩减为两层循环
详细的C代码如下:
#include<stdio.h>
int main()
{
int n = 1000, k = 500, sum = 0, x, y, sum1 = 0;
/*首先考虑相邻情况*/
sum += (n - 1) * n * 2;
/*再考虑对角情况*/
sum += (n - 1) * (n - 1) * 2;
/*最后考虑一般情况*/
for(x = 1; x <= n - 1; x++)
for(y = 1; y <= n - 1; y++)
{
if(x / y != 1 && x*x + y*y <= k*k)
{
sum1 += (n - y) * (n - x) * 2;
sum1 %= 1000000007;
}
}
sum += sum1;
printf("共有%d对小朋友可以互相看见\n",sum);
return 0;
}
运行结果是
但是实际答案是
916585708
这就很伤脑筋了
我用了题目的测试数据,进行验证
第一个n = 2, k = 1, sum = 4
嗯,没毛病
第二个n = 2,k = 2, sum = 6
嗯,也没毛病
第三个n = 3, k = 2, sum = 20
WK,确定答案没有问题吗!!!
反正我的答案就是这个955681906
欢迎各位评论区下讨论