一.破碎的砝码
1.枚举
#include<stdio.h>
typedef struct data {
int num1;
int num2;
int num3;
int num4;
}data;
data dt;
int isequal(data dt, int target) {
int arr[3] = { -1,0,1 };
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
for (int k = 0; k < 3; k++)
for (int p = 0; p < 3; p++)
if (arr[i] * dt.num1 + arr[j] * dt.num2 + arr[k] * dt.num3 + arr[p] * dt.num4 == target)
return 1;
return 0;
}
void judge() {
int i, j;
for (j = 1; j <= 40; j++)
if (!(isequal(dt, j)))
break;
if (j > 40)
printf("(%d,%d,%d,%d)\n", dt.num1, dt.num2, dt.num3, dt.num4);
}
void findNum() {
int i, j, k;
i = 1;
j = i + 1;
k = j + 1;
for (i = 1; i <= 34, i < j, i < k; i++)
for (j = i + 1; j <= 40 - i, j < k; j++)
if (j != i)
for (k = j + 1; k <= 40 - i - j; k++)
if (k != j && k != i) {
int temp = 40 - i - j - k;
if (temp != i && temp != j && temp != k && temp > k) {
dt.num1 = i;
dt.num2 = j;
dt.num3 = k;
dt.num4 = temp;
judge();
}
}
}
int main() {
findNum();
return 0;
}
2.关于findNum()函数
2.1降低枚举的次数
首先,假使全部枚举必然会重复,且每一个组会重复3次。
然后,先固定第一个数,之后每一个数的开始是上一个数取值的下一个,这样能避免数与数之间的重复,结束是40减去前面的数,这样就能避免每一组数与数的重复。
并且,每一组解按照递增的顺序,这样就可以减少循坏的次数,比如第一个循坏本来要循环34次,增加判断条件之后只需14次就可以退出。