#include <stdio.h> int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); int counter = 0; for (int x = 0; x <= n; x++) { for (int y = 0; y <= n; y++) { for (int z = 0; z <= n; z++) { if (x+2*y+5*z==n) counter++; } } } printf("%d\n", counter); } return 0; }但采用这种方法编码之后提交,系统显示超时错误。看来得要改进算法才行。分析上述三重循环,我们可以利用方程中的系数减少不必要的循环。重新编码如下:
#include <stdio.h> int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); int counter = 0; for (int x = 0; x <= n; x++) { for (int y = 0; y <= (n-x)/2; y++) if ((n-x-2*y)%5==0) counter++; } printf("%d\n", counter); } return 0; }提交,仍旧超时。看来算法仍待改进。分析上述代码,我们发现,最外层循环次数越多,最里层的代码执行的次数就越多(上述代码中是if ((n-x+2*y)%5==0))。那么,我们应该怎样减少循环执行的次数呢?将最外层循环的循环次数降下来是个不错的办法。怎么降?分析方程X+2Y+5Z=N发现,系数越大的变量,其可能的取值个数就越小。而在方程X+2Y+5Z=N中Z的系数最大,Y其次。我们可以将其放在循环外侧,其次是Y。这样,我们就避免了对X计数。编码如下:
#include <stdio.h> int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); int counter = 0; for (int z = 0; z <= n/5; z++) { for (int y = 0; y <= (n-5*z)/2; y++) if (n-5*z-2*y >= 0) counter++; } printf("%d\n", counter); } return 0; }提交,仍旧超时。看来通过暴力枚举解的方案是行不通的了。但不要沮丧,虽然代码没能提交通过,但在不断尝试的过程中,我们已经最大限度的减少了不必要的循环,正在逐步的向目标靠近。而系统提示超时预示着程序仍有改进的空间。
通过上述分析,我们就不在需要将原有代码中的内部for循环了。取而代之的,是一个简单的计算语句。代码如下:
int counter = 0; for (int z = 0; z <= n/5; z++) counter += (n-5*z)/2 + 1;当然,也可以将y放在外层循环,代码如下:
int counter = 0; for (int y = 0; y <= n/2; y++) counter += (n-2*y)/5 + 1;
显然,采用Z变量进行分类,程序循环执行的次数是最少的。于是完整编码如下所示:
#include <stdio.h> int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); int counter = 0; for (int z = 0; z <= n/5; z++) counter += (n-5*z)/2 + 1; printf("%d\n", counter); } return 0; }
#include <stdio.h> int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); long long counter = 0; while (n >= 0) { counter += n / 2 + 1; n -= 5; } printf("%lld\n", counter); } return 0; }
#include <iostream> using namespace std;然后将printf("%lld\n", counter);改写为cout << counter << endl;即可。
#include <stdio.h> int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); _int64 counter = 0; while (n >= 0) { counter += n / 2 + 1; n -= 5; } printf("%I64d\n", counter); } return 0; }