四重循环的复杂度为O(n4)若1<=n<=1000则为n12,不能满足要求。
#include<cstdio>
const int max_n = 50;
int main() {
int n, m, k [max_n];
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", k[i]);
}
bool f = false;
//通过四重循环枚举所有方案
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
for (int c = 0; c < n; c++) {
for (int d = 0; d < n; d++) {
if (k[a] + k[b] + k[c] + k[d] == m) {
f = true;
}
}
}
}
}
if (f)puts("yes");
else puts("no");
return 0;
}
故需要改进
这里使用二分搜索与O(n^3logn)的算法
*排序O(nlogn)时间;
*循环O(n^3logn)时间;
#include<cstdio>
#include<iostream>
const int max_n = 50;
int n, m, k[max_n];
bool binary_search(int x) {
//x的存在范围是k[1],k[2].....k[r-1]
int l = 0, r = n;
//反复操作直到存在范围为空
while (r - 1 >= 1) {
int i = (l + r) / 2;
if (k[i] == x)return true;
else r = i;
}//没找到x
return false;
}
void solve() {
//为了二分查找先排序
sort(k, k + n);
bool f = false;
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
for (int c = 0; c < n; c++) {
//将最内侧的循环替换成二分查找
if (binary_search(m-k[a]-k[b]-k[c])) {
f = true;
}
}
}
}
if (f)puts("yes");
else puts("no");
}
可以利用等式关系,使用O(n^2logn)的算法
即找到k(c)+K(d)=m-k(a)-k(b)是否存在,需要先将c、d组合的n^2个数字排好序
再使用二分搜索
*排序O(n^2logn)时间;
*循环O(n^2logn)时间;
int n, m, k[max_n];
int kk[max_n * max_n];
bool binary_search(int x) {
int l = 0, r = n*n;
while (r - 1 >= 1) {
int i = (l + r) / 2;
if (kk[i] == x)return true;
else if (kk[i] < x)l = i + 1;
else r = i;
}
return false;
}
void solse() {
for (int c = 0; c < n; c++) {
for (int d = 0; d < n; d++) {
kk[c * n + d] = k[c] + k[d];
}
}
sort(kk, kk + n * n);
bool f = false;
for (int a = 0; a < n; a++) {
for (int b = 0; b < n; b++) {
if (binary_search(m - k[a] - k[b] )) {
f = true;
}
}
}
}