抽签

来源:互联网 发布:nsis error修复软件 编辑:程序博客网 时间:2024/04/28 12:03

题目描述:将写有数字的n个字片放入口袋,从口袋中抽取四次,每次记下数字,然后放回。问是否存在四个数字满足相加和为m

法一:普通迭代,复杂度O(n^4)

#include <cstdio>#include <iostream>using namespace std;int main(){int n,m,array[105];cin>>n>>m;for(int i=0;i<n;i++){cin>>array[i];}for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int t=0;t<n;t++){for(int x=0;x<n;x++){if(array[i]+array[j]+array[t]+array[x]==m)printf("%d+%d+%d+%d=%d\n",array[i],array[j],array[t],array[x],m);}}}}return 0;}
法二:条件变形

题意是a+b+c+d=m,可变形为d=m-a-b-c,即原条件的四重迭代找四个数字演变为先穷举三个数的取值,然后确定m-a-b-c,再去二分查找,满足等于m-a-b-c的数(这么想的初衷是通过二分查找降低查找一个数的复杂度)   复杂度: 排序->nlogn  迭代->n^3logn  总:n^3logn

#include <cstdio>#include <algorithm>#include <iostream>using namespace std;int binary_search(int array[],int num,int left,int right){int middle;while(left<=right){middle=(left+right)/2;if(array[middle]==num)return 1;else if(array[middle]>num)right=middle-1;elseleft=middle+1;}return 0;}int main(){int n,m,array[105];cin>>n>>m;for(int i=0;i<n;i++){cin>>array[i];}sort(array,array+n);for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int t=0;t<n;t++){int sum=array[i]+array[j]+array[t];if(binary_search(array,m-sum,0,n-1)){printf("%d+%d+%d+%d=%d\n",array[i],array[j],array[t],m-sum,m);}}}}return 0;}
法三:优化

再变形为c+d=m-a-b

复杂度: 排序->n^2logn   迭代->n^2logn 总:n^2logn

不过为了使用二分查找,要提前把c+d的所有取值存起来

#include <cstdio>#include <algorithm>#include <iostream>using namespace std;void binary_search(int t[],int num,int left,int right,int array[],int n,int i,int j,int m){int middle;while(left<=right){middle=(left+right)/2;if(t[middle]==num){printf("%d+%d+%d+%d=%d\n",array[i],array[j],array[middle/n],array[middle%n],m);return;}else if(t[middle]>num)right=middle-1;elseleft=middle+1;}}int main(){int n,m,array[105],t[10025];cin>>n>>m;for(int i=0;i<n;i++){cin>>array[i];}for(int i=0;i<n;i++){for(int j=0;j<n;j++){t[i*n+j]=array[i]+array[j];}}sort(t,t+n*n);for(int i=0;i<n;i++){for(int j=0;j<n;j++){int sum=array[i]+array[j];binary_search(t,m-sum,0,n*n-1,array,n,i,j,m);}}return 0;}




1 0
原创粉丝点击