二分答案法例题,用于练习二分答案的基本思想非常合适,包括了思维方式转换的内容(以前我们所做的一直是利用二分法求得数组元素对应指针之类,但是现在是直接对答案进行枚举)。

思路是:首先对输入数组进行排序,使得a,b两数组都相对有序。

接下来对每个数字进行二分枚举,之后,通过判断这个数组当前的排名来进行下一步的二分。

对于每个数字排名的方式通过对枚举每一个a数组中的位置来确定,之后二分对应的数组元素的位置得到,时间复杂度是NLOGN;

整个算法时间复杂度是NLOGNLOG(N*N)带入50000计算得到的值大概是两千六百万的样子,实际加上cin.sync_with_stdio(false);跑出来的结果大概是300毫秒的样子。。看上去51nod的服务器还是比较快的。事实上,因为输入数据量大,使用输入优化一定程度上有些奇妙的速度优势。但是其实不加这个优化大概时间在500毫秒,其实也是差不多的。

说实话当时再设计完这个代码的时候超级心虚。。。觉得随便那个常数没搞好就得玩炸了。。。。结果来看危险也许是挺危险,但是也还有一定的容错空间。

最初的再设计出来统计大于某元素数量的方式之后发现复杂度有点小爆炸。。。以至于对于进一步的爆炸设计有些心虚。。。。

当时提出的替代方案是首先从A中枚举在一个数字,让他满足A[K]*B[0]<TARGET&&A[K]*B[N-1]>TARGET

之后进行下一部枚举——找到一个B元素,使得A[k]*B[I]<TARGET&&A[K]*B[I+1]>TARGET

之后使用B[I]反推A[I]。但是发现只这种方法其实要正确实现复杂度反而比之前的方案复杂度更高,因为在反推这一步没法使用二分法——无法凭空确定是哪个A[k]正好能满足要求,也同时无法确定B[I]先去的正确性。。。。于是,GG。

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105

下面是代码:

 #include<bits/stdc++.h>
using namespace std;
const long long MAXN=;
long long a[MAXN];
long long b[MAXN];
long long n,k;
void init()
{
cin>>n>>k;
for(int i=;i<n;++i)
{
cin>>a[i]>>b[i];
}
sort(a,a+n);
sort(b,b+n);
}
long long calculate(long long key)
{
long long ret=;
for(int i=;i<n;++i)
{
long long tar=key/a[i];
if(tar*a[i]!=key)tar++;
long long pos=lower_bound(b,b+n,tar)-b;
ret+=pos;
}return ret;
}
long long step(long long a,long long b,long long target)
{
if(a==b-)return a;
long long mid=(a+b)/;
long long res=calculate(mid);
if(res<=target)return step(mid,b,target);
else return step(a,mid,target); }
int main()
{
cin.sync_with_stdio(false);
init();
cout<<step(a[]*b[],a[n-]*b[n-]+,n*n-k);
return ;
}

代码其实很好写。。。但是因为没带电脑等等原因,这份代码差不多是大的第四遍了。。。。。。

另外就是发现了一点,加了输入优化反而更慢了,下面是加了输入优化的AC代码:

#include<bits/stdc++.h>
using namespace std;
const long long MAXN=;
long long a[MAXN];
long long b[MAXN];
long long n,k;
void read_(long long &ret)
{
ret=;
char c=;
while((c<''||c>''))c=getchar();
while(c>=''&&c<='')ret*=,ret+=c-'',c=getchar();
}
void init()
{
// cin>>n>>k;
read_(n);
read_(k);
for(int i=;i<n;++i)
{
// cin>>a[i]>>b[i];
read_(a[i]);
read_(b[i]);
}
sort(a,a+n);
sort(b,b+n);
} long long calculate(long long key)
{
long long ret=;
for(int i=;i<n;++i)
{
long long tar=key/a[i];
if(tar*a[i]!=key)tar++;
long long pos=lower_bound(b,b+n,tar)-b;
ret+=pos;
}return ret;
}
long long step(long long a,long long b,long long target)
{
if(a==b-)return a;
long long mid=(a+b)/;
long long res=calculate(mid);
if(res<=target)return step(mid,b,target);
else return step(a,mid,target); }
int main()
{
cin.sync_with_stdio(false);
init();
cout<<step(a[]*b[],a[n-]*b[n-]+,n*n-k);
return ;
}

51nod 1105 二分答案法标准题目的更多相关文章

  1. 51nod 1105 二分好题

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1105 1105 第K大的数 基准时间限制:1 秒 空间限制:131072 ...

  2. 51nod 1799 二分答案(分块打表)

    首先题目等价于求出满足运行二分程序后最后r=k的排列种数. 显然对于这样的二分程序,起作用的只有mid点,mid处的值决定了接下来要递归的子区间. 于是可以一遍二分求出有多少个mid点处的值<= ...

  3. 51NOD 1128正整数分组V2 二分答案

    这道题是典型的二分答案法.但是首先难道这道题的时候我进行了一系列的思考,甚至联想到了之前多校中类似于树状划分的问题...原因是大家都包括N各节点K个输入.. 实际上最开始联想到了应当使用二分法“枚举” ...

  4. 【二分答案】 【POJ3497】 【Northwestern Europe 2007】 Assemble 组装电脑

    Assemble Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3171   Accepted: 1013 Descript ...

  5. POJ 2723 Get Luffy Out(2-SAT+二分答案)

    Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8851   Accepted: 3441 Des ...

  6. 51nod 1105 第K大的数 【双重二分/二分套二分/两数组任意乘积后第K大数】

    1105 第K大的数  基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...

  7. POJ 3273-Monthly Expense 求分组和的最小的最大值【二分答案】

    题目链接:http://poj.org/problem?id=3273 题目大意:给出一个有n个数据的数组,将其分为连续的m份,找到一种分法,是的m份中最大一份总和最小 解题思路: 直接在答案的区间内 ...

  8. LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

    #2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  9. 洛谷P2801 教主的魔法 [分块,二分答案]

    题目传送门 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. ...

随机推荐

  1. 50个必备的jQuery代码段

    本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够帮助 ...

  2. 关于安卓visualizer的用法

    看别人显示播放wav文件显示频谱写的代码都是断断续续的,在这里我贴了完整的代码,给有需要的人做参考,显示频谱还没有完成,不知道怎么弄,已经可以得到byte[] fft数据了,参考别人的写法也可以开方取 ...

  3. Java并发(三):实例引出并发应用场景

    前两篇介绍了一些Java并发的基础知识,博主正巧遇到一种需求:查询数据库,根据查询结果集修改数据库记录,但整个流程是做成了一个schedule的,并且查询比较耗时,并且需要每两分钟执行一次,cpu经常 ...

  4. html便民查询各个工具类实例代码分享(支持pc和移动端)

    1.手机号码查询 <iframe id="api_iframe_51240" name="api_iframe_51240" src="&quo ...

  5. <Android 应用 之路> 天气预报(五)

    前言 写了上一篇文章,讲了下这个实现天气预报的使用内容,现在又到了看代码的时候,主要还是贴代码,然后添加足够的注释. 聚合数据SDK配置 将juhe_sdk_v_X_X.jar以及armeabi文件夹 ...

  6. 【Android开发笔记】底部菜单栏 FragmentTabHost

    公司项目,需求本来是按照谷歌官方指南写的,菜单栏设计成在导航栏下方 结果呢,审评时,BOSS为了和iOS统一,改成了底部菜单栏(标准结局),我只能呵呵呵呵呵呵呵 查了查资料发现实现底部菜单栏用的是Fr ...

  7. zabbix中监控项报错

    报错信息: zabbix报错(Not all processes could be identified, non-owned process info will not be shown, you ...

  8. UVA 340 Master-Mind Hints 猜密码游戏(水)

    题意: 给一串密码(第一行),接着再给你很多行猜测,针对每行猜测,输出两个数字,分表代表:同一列上匹配的个数,不同列上匹配的个数.注:匹配指的是一次,一旦配对,不能再与其他配对. 思路: 每接受一行猜 ...

  9. 获取win10 Insider Preview报错0x80080300

    获取win10 Insider Preview报错0x80080300 1.msconfig2.隐藏Microsoft 服务3.disable 剩下的服务4.win + i, Update&s ...

  10. pat乙级1052

    输出“\”字符: cout << "\\"; 因为‘\’是转义字符,例如“\n”代表换行. 同理,printf输出“%”: printf("%%") ...