数据结构即是研究数据的各种 逻辑结构和 存储结构,以及在此基础上对数据的各种 操作。
抽签问题
题目
将写有数字的n
个纸片放入口袋中,从口袋中抽取4
次纸片,记下纸片上的数字后将其放回口袋(可重复抽取同一纸片)。如果抽取4次后获得的数字之和为m
,就算胜出。
编写一个程序判断当纸片上的数字是k1,k2,...,kn
时,是否存在抽取4次之和为m的方案。
方法1
枚举每一种抽取方案,判断是否存在一种方案使得抽到的数字之和为m,即vi[i] + vi[j] + vi[k] + vi[h] == m
。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
int m;
while (cin >> n >> m) {
vector<int> vi(n);
for (int i = 0; i < n; ++i) {
cin >> vi[i];
}
bool f = false;
for (int i = 0; i < n && !f; ++i) {
for (int j = 0; j < n && !f; ++j) {
for (int k = 0; k < n && !f; ++k) {
for (int h = 0; h < n && !f; ++h) {
if (vi[i] + vi[j] + vi[k] + vi[h] == m) {
f = true;
}
}
}
}
}
if (f) {
cout << "true" << endl;
}
else {
cout << "false" << endl;
}
}
return 0;
}
时间复杂度为O(N4)。
方法2
采用二分查找,判断是否存在vi[h] == m - vi[i] - vi[j] - vi[k]
。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
int m;
while (cin >> n >> m) {
vector<int> vi(n);
for (int i = 0; i < n; ++i) {
cin >> vi[i];
}
sort(vi.begin(), vi.end());
bool f = false;
for (int i = 0; i < n && !f; ++i) {
for (int j = 0; j < n && !f; ++j) {
for (int k = 0; k < n && !f; ++k) {
if (binary_search(vi.begin(), vi.end(), m - vi[i] - vi[j] - vi[k])) {
f = true;
}
}
}
}
if (f) {
cout << "true" << endl;
}
else {
cout << "false" << endl;
}
}
return 0;
}
时间复杂度为O(N3logN)。
方法3
使用一个数组保存vi[i] + vi[j]
或vi[k] + vi[h]
的所有结果,采用二分查找,判断是否存在vi[k] + vi[h] == m - vi[i] - vi[j]
。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
int m;
while (cin >> n >> m) {
vector<int> vi(n);
for (int i = 0; i < n; ++i) {
cin >> vi[i];
}
vector<int> vin(n * n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
vin[i * n + j] = vi[i] + vi[j];
}
}
sort(vin.begin(), vin.end());
bool f = false;
for (int i = 0; i < n && !f; ++i) {
for (int j = 0; j < n && !f; ++j) {
if (binary_search(vin.begin(), vin.end(), m - vi