二分查找 HDOJ 2141 Can you find it?

题目传送门

 1 /*
 2      题意:给出一个数,问是否有ai + bj + ck == x
 3      二分查找:首先计算sum[l] = a[i] + b[j],对于q,枚举ck,查找是否有sum + ck == x
 4 */
 5 #include <cstdio>
 6 #include <algorithm>
 7 #include <cmath>
 8 using namespace std;
 9
10 typedef long long ll;
11 const int MAXN = 5e2 + 10;
12 const int INF = 0x3f3f3f3f;
13 ll a[MAXN], b[MAXN], c[MAXN];
14 ll sum[MAXN*MAXN];
15 int tot;
16
17 bool my_binary_search(int l, int r, ll k)   {
18     while (l < r)   {
19         int mid = (l + r) >> 1;
20         if (sum[mid] == k)  return true;
21         else if (sum[mid] > k)  r = mid;
22         else    l = mid + 1;
23     }
24     return false;
25 }
26
27 int main(void)  {       //HDOJ 2141 Can you find it?
28     //freopen ("HDOJ_2141.in", "r", stdin);
29
30     int l, n, m, s, cas = 0;
31     while (scanf ("%d%d%d", &l, &n, &m) == 3)   {
32         for (int i=1; i<=l; ++i)    scanf ("%I64d", &a[i]);
33         for (int i=1; i<=n; ++i)    scanf ("%I64d", &b[i]);
34         for (int i=1; i<=m; ++i)    scanf ("%I64d", &c[i]);
35         scanf ("%d", &s);
36
37         printf ("Case %d:\n", ++cas);
38         sort (a+1, a+1+l);  sort (b+1, b+1+n);  sort (c+1, c+1+m);
39         tot = 0;
40         for (int i=1; i<=l; ++i)    {
41             for (int j=1; j<=n; ++j)    {
42                 sum[++tot] = a[i] + b[j];
43             }
44         }
45         sort (sum+1, sum+1+tot);
46
47         ll mn = a[1] + b[1] + c[1], mx = a[l] + b[n] + c[m];
48         while (s--) {
49             ll q;  scanf ("%I64d", &q);
50             if (q < mn || q > mx)   {
51                 puts ("NO");    continue;
52             }
53             bool flag = false;
54             for (int i=1; i<=m; ++i)    {
55                 int p = lower_bound (sum+1, sum+1+tot, q - c[i]) - sum;
56                 if (p < 1 || p > tot)   continue;
57                 if (sum[p] + c[i] == q) {
58                     flag = true;    puts ("YES");   break;
59                 }
60                 //if (my_binary_search (1, tot, q - c[i]))    {
61                     //flag = true;    puts ("YES");   break;
62                 //}
63             }
64             if (!flag)  {
65                 puts ("NO");
66             }
67         }
68     }
69
70     return 0;
71 }
时间: 2024-08-07 19:37:17

二分查找 HDOJ 2141 Can you find it?的相关文章

hdoj 2141 Can you find it?【二分查找+暴力】

Can you find it? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/Others)Total Submission(s): 17036    Accepted Submission(s): 4337 Problem Description Give you three sequences of numbers A, B, C, then we give you a number

hdu 2141 Can you find it?(二分查找)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2141 题目大意:查找是否又满足条件的x值. 这里简单介绍一个小算法,二分查找. 1 /* 2 3 x^2+6*x-7==y 4 输入y 求x 精确度为10^-5 5 0=<x<=10000 6 7 */ 8 #include <iostream> 9 #include <cstdio> 10 using namespace std; 11 int main (void) 1

二分查找+数学 HDOJ 4342 History repeat itself

题目传送门 题意:计算从1开始到第n个非完全平方数的开方和 分析:设第n个非完全平方数的值为a,x * x < a < (x+1) * (x+1),而且易得(tmp = sqrt (a) ) == x,a之前的非完全平方数的个数为a - tmp,所以可以二分查找a - tmp == n的a,然后模拟一下能计算出前a个数的开方和 收获:二分查找是个好方法 代码: /************************************************ * Author :Running

离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers

题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前花开的数量,放张图易理解: 还有一种做法用尺取法的思想,对暴力方法优化,对询问点排序后再扫描一遍,花开+1,花谢-1.详细看代码. 收获:一题收获很多:1. 降低复杂度可以用二分 2. 线段计数问题可以在端点标记1和-1 3. 离散化+线段树 终于会了:) (听说数据很水?) 代码1:离散化+线段树

hdu 2141 Can you find it?(二分查找变例)

Problem Description Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X. Input There are many cases. Every data case

二分查找

递归版(在区间[x, y)中找v的位置) 1 //递归版二分查找 2 int bsearch(int * A, int x, int y, int v) 3 { 4 5 if(v<a[x] || v>a[y-1]) return -1; 6 int m = x + (y-x)/2; //此处能不能用int m = (x+y)/2,需要仔细考虑(暂时想不到原因) 7 if(A[m]==v) return m; 8 else if(A[m]>v) return bsearch(A, x, m

二分查找总结

最近刷leetcode和lintcode,做到二分查找的部分,发现其实这种类型的题目很有规律,题目大致的分为以下几类: 1.最基础的二分查找题目,在一个有序的数组当中查找某个数,如果找到,则返回这个数在数组中的下标,如果没有找到就返回-1或者是它将会被按顺序插入的位置.这种题目继续进阶一下就是在有序数组中查找元素的上下限.继续做可以求两个区间的交集. 2.旋转数组问题,就是将一个有序数组进行旋转,然后在数组中查找某个值,其中分为数组中有重复元素和没有重复元素两种情况. 3.在杨氏矩阵中利用二分查

二分查找JAVA实现

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. 一.概念 二分查

rwkj 1430 二分查找

#include<iostream>using namespace std;int n,k,a[10000]; int binsearch(int low,int high){ int i,len,s;while(low<high) { len=(high+low)/2; for(s=0,i=0;i<n;i++) s+=a[i]/len; if(s>k) low=len+1; else if(s<k) high=len-1; else return len; }}int