/* P20页:难度增加的抽签问题 核心:处理大数据时,二分查找算法lgn的时间复杂度是很省时间的 问题:n个签,有放回抽取4次,求和是否有可能为m,n<1000 解决:1。四次循环得到4只签求和后和m比较,时间复杂度为n^4,12个0,不行 2。三次循环后得到三支签k1,k2,k3,然后二分查找最后一只签m-k1-k2-k3,找到则返回ture,否则返回false,时间为n^3lgn,10个0,不行 3。二次循环后得到二只签k1, k2,枚举2只签的和的n^2种情况并排序,然后再其中二分查找n-k1-k2。排序的时间复杂度为n^2lgn^2=2n^2lgn=o(n^2lgn),二次循环加二分查找的时间复杂度为o(n^2lgn^2),总的时间复杂度为n^2lgn, 7个0,可以轻松运行处结果*/#include#include #include #include using namespace std;const int Max = 1010;int n, m;int k[Max];int main(void){ int k_enum[2*Max]; int it0 = 0; cin >> n >> m; for (int i = 0; i < n; i++) cin >> k[i]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { k_enum[it0] = k[i] + k[j]; it0++; } sort(k_enum, k_enum + n * n); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if( binary_search(k_enum, k_enum+n*n, m-k[i]-k[j]) ) { cout << "Yes"; return 0; } } cout << "No"; return 0;}