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

思路是:首先对输入数组进行排序,使得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. The program 'unzip' is currently not installed. You can install it by typing:

    linux解压遇到下面问题: The program 'unzip' is currently not installed. You can install it by typing: sudo ap ...

  2. 判断dataset表中是否存在 某列

    DataSet ds ; ds.Tables[0].Columns.Contains("a") 同样适用于 datarow dr ; dr.Table.Columns.Contai ...

  3. UITableViewCellStyle 四种样式

    四种样式如下:

  4. webpack 的异步组件 生成commonchunks

    new webpack.optimize.CommonsChunkPlugin({ async: 'async-common', minChunks: function (module, count) ...

  5. react的setState使用中遇到的问题

    setState()更新的数据和自己预期的不一致 对 React 新手来说,使用 setState 是一件很复杂的事情.即使是熟练的 React 开发,也很有可能因为 React 的一些机制而产生一些 ...

  6. spring-framework-3.0.2RELEASE之后为啥没有依赖包了?

    缘起:莫莫接到新任务要学习spring mvc,于是在网上找了个demo文档跟着一起做.这个是学习的网址: http://www.open-open.com/doc/view/a6462d9a2e2b ...

  7. JAVA和数据库工具的下载地址(备用)

    sqlite数据库驱动下载: http://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/

  8. web调试的一些小技巧

    1.不带缓存的刷新,用于刷新css或者js:Ctrl+F5 待续...

  9. hihoCoder hiho一下 第二周 #1014 : Trie树(Trie树基本应用)

    思路: 完全看题目中的介绍就行了.还有里面的input写道:不保证是英文单词,也有可能是火星文单词哦.比赛结束后的提交是不用考虑26个字母之外的,都会AC,如果考虑128种可能的话,爆了内存.步骤就是 ...

  10. http头部信息学习

    想的每2周进行知识的总结,自己拖延症有犯了,发现自己知识库量还是太少,平时总结和发现问题还不够深,对待问题的深度也存在很多问题,但是坚持学习,总结,后面应该会有收获, 1.常见的返回码 100: 请服 ...