题目:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2157
题目描述
Saya likes math, because she think math can make her cleverer.
输入
The input consists of several test cases.
输出
For each case, print the case number (1, 2 …) and the GN.
示例输入
2 10
示例输出
Case 1: 8
题目要求就是 给你N个数,用不多于4个数组成不大于M的最大的数,所给的数使用次数不限。
用样例解释:N为2,M为10,就是用2和100组成一个不大于10的最大的数。
100大于10了,显然舍弃,剩下2可以用多次,因为最多用4个数组成一个数,所以2用4次得到8。
这道题的解题思路比较巧妙,要求组成一个数的个数小于等于4,我们就可以让组成0个数的(也就是0),一个数的(输入的数本身),和所有任意两个数的和存入一个数组中。
这样数组内任意两个数相加的和 就代表了任意的1~4个数组成的数。
最后再用二分查找,找一下符合要求的,就OK了。~\(≧▽≦)/~啦啦啦
对了,在查找前不要忘了排序呀。
#include <iostream> #include <string.h> #include <algorithm> using namespace std; int arr[1001000]; int N,M; // 二分查找 int binary_sort(int len) { int i,l,h,mid,aim; aim=0; for(i=0; i<len; ++i) { l=0;h=len; while(l<h) //对当前的数用二分查找法查找另一个满足要求的数 { mid=(l+h)/2; if(arr[mid]+arr[i]<=M) { if(arr[i]+arr[mid]>=aim) aim=arr[i]+arr[mid]; l=mid+1; } else h=mid; } } return aim; } int main() { int i,j,k,len,test,temp; test=1; while(cin>>N>>M) { if(!N && !M) break; memset(arr,0,sizeof(arr)); k=1; // 将每个数都存入数组 for(i=0;i<N;++i) { cin>>temp; if(temp>M) continue; arr[k++]=temp; } // 如果输入数据中有最大值,直接输出. len=k; // 将任意两个数的和存入数组 for(i=1;i<len;++i) for(j=1;j<len;++j) arr[k++]=arr[i]+arr[j]; // 由小到大排序,便于后面二分查找 sort(arr,arr+k); cout<<"Case "<<test++<<": "<<binary_sort(k)<<endl; cout<<endl; } return 0; }