1、POJ 3258 River Hopscotch

  题意:给出小溪的长度L,给出河中石头数N和最多可移动的石头数M,使得每两颗相邻石头、起点与第一颗石头、终点与最后一颗石头之间的最小距离最大。

  思路:二分最小距离,然后把间距小于该距离的石头移除,如果移除的石头数大于M,说明该距离太大,否则可以尝试增大该距离。

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int L, N, M;
 5 int st, ed;
 6 const int maxn = 50005;
 7 int Rocks[maxn];
 8 bool Judge(int dis)
 9 {
10     int rmvrocks = 0;
11     int tdis = 0;
12     int refpos = 0;
13     int tnumrocks = 0;
14     for (int i = 0; i < N;)
15     {
16         tnumrocks = 0;
17         while (i<N&&Rocks[i] - refpos < dis) tnumrocks++,i++;
18         rmvrocks += tnumrocks;
19         refpos = Rocks[i];
20         i++;
21     }
22     if (tnumrocks == 0 && L - Rocks[N - 1] < dis) rmvrocks++;
23     if (rmvrocks > M) return false;
24     else return true;
25 }
26 int main()
27 {
28     while (cin >> L)
29     {
30         cin >> N >> M;
31         for (int i = 0; i < N; i++) cin >> Rocks[i];
32         sort(Rocks, Rocks + N);
33         int mindis = Rocks[0];
34         for (int i = 1; i < N; i++)
35             if (Rocks[i] - Rocks[i - 1] < mindis) mindis = Rocks[i] - Rocks[i - 1];
36         if (L - Rocks[N - 1] < mindis) mindis = L - Rocks[N - 1];
37         int l = mindis, r = L;
38         while (l <= r)
39         {
40             int mid = (l + r) / 2;
41             if (Judge(mid)) l = mid + 1;
42             else r = mid - 1;
43         }
44         cout << r << endl;
45     }
46     return 0;
47 }

View Code

2、POJ 3104 Drying

  题意:给出n件衣服,每件衣服上都有wi的水分,每次要么把一件衣服放在烘炉上,每分钟至多减少k的水分,要么自然烘干,每分钟减少1的水分,同一时间最多只能把一件衣服放在烘炉上。求所有衣服都烘干的最小时间。

  思路:二分总时间,记为为t,设此时所需用烘炉的时间为tx=0.为使总时间最小,那么要尽可能利用烘炉,直至所有衣服被烘干之前的每分钟都有把某一件衣服放在烘炉上,我们则统计出该时间,如果小于等于t,说明我们还可以尝试减少时间,否则,只能增大时间。接下来要统计出tx.第i件衣服的水分为wi.如果wi<t,则让其自然烘干即可;否则,由于只需要ceil((wi-x)/(k-1))的用烘炉的时间,剩下的水分让其自然烘干。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstdio>
 5 using namespace std;
 6 #define MAXN 100000+10
 7 #define LL long long
 8 int n, k;
 9 int wat[MAXN];
10
11 bool Judge(int x)
12 {
13     LL t = 0;
14     for (int i = 0; i<n; i++)
15     {
16         if (wat[i]>x)
17         {
18             int xx = ceil((wat[i] - x)*1.0 / (k - 1));
19             t += xx;
20         }
21         if (t>x)return false;
22     }
23
24     if (t>x)return false;
25     else return true;
26 }
27 int main()
28 {
29     while (~scanf("%d", &n))
30     {
31         int l = 1, r = 0;
32         for (int i = 0; i<n; i++)
33         {
34             scanf("%d", &wat[i]);
35             r = max(r, wat[i]);
36         }
37         scanf("%d", &k);
38
39         if (k == 1)
40         {
41             printf("%d\n", r);
42             continue;
43         }
44         int mid = 0;
45         while (l <= r)
46         {
47             mid = (l + r) / 2;
48             if (Judge(mid))
49             {
50                 r = mid - 1;
51             }
52             else
53                 l = mid + 1;
54         }
55         printf("%d\n",l);
56     }
57     return 0;
58 }

View Code

3、poj2976-Dropping tests(0-1分数规划)

  题意:有n次测试,每次测试对ai道题,总共bi道题。现在,你可以在最多除去k次的测试,使得剩下的测试中总正确率(剩下测试的对的总题数/剩下测试的总题数)最高。

  思路:二分总正确率,对于当前假设正确率x,对于每个测试,其额外做对的题目为ai-x*bi(也可以看成贡献度),然后去掉最小的k次,累加前面大的n-k次,如果算出来正确率可以超过x,则可以尝试增大x,否则,只能减小x.

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn = 1010;
 5 int n, k;
 6 struct Score
 7 {
 8     int a;
 9     int b;
10 }tests[maxn];
11 long long suma, sumb;
12
13 double tt;//假设的当前正确率
14 bool Cmp(const Score&a, const Score&b)
15 {
16     return a.a - tt*a.b > b.a - tt*b.b;//对当前正确率贡献度大的排前面
17 }
18
19 bool Judge(double rt)
20 {
21     tt = rt;
22     sort(tests, tests + n, Cmp);
23     long long sum1 = 0, sum2 = 0;
24     for (int i = 0; i < n; i++)
25     {
26         if(i<n-k)sum1 += tests[i].a, sum2 += tests[i].b;
27         else if (tests[i].a - rt*tests[i].b > 1e-4) sum1 += tests[i].a, sum2 += tests[i].b;
28     }
29     if (1.0*sum1 / sum2 >= rt) return true;
30     else return false;
31 }
32
33 int main()
34 {
35     while (cin >> n >> k, n != 0 || k != 0)
36     {
37         suma = sumb = 0;
38         for (int i = 0; i < n; i++)
39         {
40             cin >> tests[i].a;
41             suma += tests[i].a;
42         }
43         for (int i = 0; i < n; i++)
44         {
45             cin >> tests[i].b;
46             sumb += tests[i].b;
47         }
48         double L = 1.0*suma / sumb;
49         double R = 1.0;
50         while (R - L > 1e-4)
51         {
52             double mid = (L + R) / 2;
53             if (Judge(mid)) L = mid;
54             else R = mid;
55         }
56         printf("%.lf\n", L*100);
57     }
58     return 0;
59 }

View Code

4、poj 3685 Matrix

  题意:对于n*n的矩阵,第i行第j列的数字为i*i + 100000 * i + j*j - 100000 * j + i*j。求第m小的元素值。

  思路:从式子可以看出每列中的数字按行递增。然后二分答案,然后对于每列二分,找到第一个大于等于该答案的位置,然后就可以知道该列中小于该答案的数字的个数。统计出所有的个数,如果个数大于m,说明该答案还可以减小,否则的话需要增大。

 1 //先对答案进行二分,求满足小于等于该答案的个数(求法:由于每列从上到下的值递增,对每一列找到第一个大于答案的值,然后累加个数),若个数太多,则说明答案太大,否则太小。
 2 #include<iostream>
 3 #include<cstdio>
 4 using namespace std;
 5 const long long INF = 1LL << 50;
 6 long long f(long long i, long long j)
 7 {
 8     return i*i + 100000 * i + j*j - 100000 * j + i*j;
 9 }
10 long long n, m;
11 bool Judge(long long tans)
12 {
13     long long num = 0;
14     for (int j = 1; j <= n; j++)
15     {
16         int l = 1, r = n;
17         while (l <= r)
18         {
19             int mid = (l + r) / 2;
20             if (f(mid, j) > tans)
21             {
22                 r = mid - 1;
23             }
24             else l = mid + 1;
25         }
26         num += l - 1;
27     }
28     if (num >= m) return true;
29     else return false;
30 }
31 int main()
32 {
33     int t;
34     cin >> t;
35     while (t--)
36     {
37         scanf("%lld%lld", &n, &m);
38         long long R = INF, L = -INF;
39         while (L <= R)
40         {
41             long long mid = (L + R) >> 1;
42             if (Judge(mid))
43             {
44                 R = mid - 1;
45             }
46             else L = mid + 1;
47         }
48         printf("%lld\n", L);
49     }
50     return 0;
51 }

View Code

5、poj 3662 Telephone Linse

  题意:有N个电线杆,给出P条可以连接的电线,其中K条可以免费,求存在1到N的一条路径,若连接的电线数目小于K条,则为0;若大于,则求其除去K条电线后剩余的电线长度最大值的最小值;若不存在路径,为-1.

  思路:最优情况下免费的K条肯定取需要连接的电线从大到小前K条。那么我们二分这个最大长度mid,把大于该长度的电线的权值记为1,小于等于该长度的电线的权值记为0,求一次从1开始的最短路径,dis[N]即为大于mid长度的电线条数,如果该条数小于等于K,说明我们至多需要支付mid的价格,接下来看能不能再缩小mid;否则,只能增大mid;如果不存在路径,直接输出-1;如果mid为0时dis[N]小于等于K,则可直接输出0.

  1 #include<iostream>
  2 #include<memory.h>
  3 #include<vector>
  4 #include<queue>
  5 using namespace std;
  6 struct node
  7 {
  8     int to;
  9     int length;
 10     int weight;
 11     node(int t= 0, int l = 0,int wt=0):to(t),length(l),weight(wt){ }
 12 };
 13 vector<vector<node> >m;
 14 int dis[1005];
 15 int path[1005];
 16 bool vis[1005];
 17 int cnt[1005];
 18 int n, p, k;
 19 const int INF = 0x7fffffff;
 20 bool flag = true;
 21 bool SPFA(int src)
 22 {
 23     memset(vis, 0, sizeof(vis));
 24     memset(cnt, 0, sizeof(cnt));
 25     for (int i = 1; i <= n; i++)
 26     {
 27         dis[i] = INF;
 28         path[i] = src;
 29     }
 30     queue<int>q;
 31     q.push(src);
 32     dis[src] = 0, vis[src] = true;
 33     cnt[src]++;
 34     while (!q.empty())
 35     {
 36         int v = q.front();
 37         q.pop();
 38         vis[v] = false;
 39         int sz = m[v].size();
 40         for (int i = 0; i < sz; i++)
 41         {
 42             int u = m[v][i].to;
 43             if (dis[v] + m[v][i].weight < dis[u])
 44             {
 45                 dis[u] = dis[v] + m[v][i].weight;
 46                 path[u] = v;
 47                 if (!vis[u])
 48                 {
 49                     q.push(u);
 50                     vis[u] = true;
 51                     cnt[u]++;
 52                     if (cnt[u] > n) return false;
 53                 }
 54             }
 55         }
 56     }
 57     return true;
 58 }
 59 void Dij(int src)
 60 {
 61     memset(dis, -1, sizeof(dis));
 62     memset(vis, 0, sizeof(vis));
 63     memset(path, 0, sizeof(path));
 64     int sz = m[src].size();
 65     for (int i = 0; i < sz; i++) dis[m[src][i].to] = m[src][i].weight,path[m[src][i].to]=src;
 66     for (int i = 1; i <= n; i++) if (dis[i] == -1) dis[i] = INF;
 67     vis[src] = true, dis[src] = 0;
 68     for (int i = 1; i <= n - 1; i++)
 69     {
 70         int u = src, min = INF;
 71         for (int i = 1; i <= n; i++)
 72         {
 73             if (!vis[i] && dis[i] < min) u = i, min = dis[i];
 74         }
 75         vis[u] = true;
 76         sz = m[u].size();
 77         for (int i = 0; i < sz; i++)
 78         {
 79             int v = m[u][i].to;
 80             if (!vis[v] && dis[u] + m[u][i].weight < dis[v])
 81             {
 82                 dis[v] = dis[u] + m[u][i].weight;
 83                 path[v] = u;
 84             }
 85         }
 86     }
 87 }
 88 bool Judge(int mid)
 89 {
 90     for (int i = 1; i <= n; i++)
 91     {
 92         int sz = m[i].size();
 93         for (int j = 0; j < sz; j++)
 94         {
 95             if (m[i][j].length > mid) m[i][j].weight = 1;
 96             else m[i][j].weight = 0;
 97         }
 98     }
 99     //SPFA(1);
100     Dij(1);
101     if (dis[n] == INF) flag = false;
102     if (dis[n] <= k) return true;
103     else return false;
104 }
105 int main()
106 {
107     while (~scanf("%d%d%d", &n, &p, &k))
108     {
109         m.clear();
110         for (int i = 0; i <= n; i++) m.push_back(vector<node>());
111         int L = 0, R = 0;
112         for (int i = 1; i <= p; i++)
113         {
114             int v, u, l;
115             scanf("%d%d%d", &v, &u, &l);
116             m[v].push_back(node(u, l));
117             m[u].push_back(node(v, l));
118             if (l > R) R = l;
119         }
120         flag = true;
121         if (Judge(0))
122         {
123             printf("0\n");
124         }
125         else if (!flag)
126         {
127             printf("-1\n");
128         }
129         else
130         {
131             while (L <= R)
132             {
133                 int mid = (L + R) / 2;
134                 if (Judge(mid)) R = mid - 1;
135                 else L = mid + 1;
136             }
137             printf("%d\n", L);
138         }
139     }
140     return 0;
141 }

View Code

6、UVA 1555 - Garland(推公式,贪心,二分搜索)

  题意:有一个电线,给出最左边的电灯挂的高度,第i盏灯的高度为Hi = (H i-1 + H i+1)/2 - 1,共要挂n盏灯,并且高度不能低于地面。求最右边那盏灯的最低高度。

  思路:Hi = (H i-1 + H i+1)/2 - 1转换为Hi=2*H(i-1)+2-H(i-2)。二分第二盏灯的高度,如果没有灯的高度低于地面,则看看能不能再降低,否则只能增大。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int n;
 5 double A, B;
 6 bool Judge(double x)
 7 {//Hi=2*H(i-1)+2-H(i-2)
 8     double h1 = A, h2 = x,h3;
 9     for (int i = 3; i <= n; i++)
10     {
11         h3 = 2 * h2 + 2 - h1;
12         if (h3 < 0) return false;
13         h1 = h2, h2 = h3;
14     }
15     B = h3;
16     return true;
17 }
18 int main()
19 {
20     while (~scanf("%d%lf", &n, &A))
21     {
22         double L = 0, R = A;
23         while (R - L >= 1e-6)
24         {
25             double mid = (R + L) / 2;
26             if (Judge(mid)) R = mid;
27             else L = mid;
28         }
29         printf("%.2lf\n", B);
30     }
31     return 0;
32 }

View Code

转载于:https://www.cnblogs.com/ivan-count/p/7228957.html

二分专题(不定期更新)相关推荐

  1. 搜索专题(不定期更新)

    1.POJ 2386  Lake Counting 题意:给出一块区域,询问有多少个湖泊? 思路:DFS,对于'W',深搜一次,并标记已访问.之后每次对未访问的'W'做一次深搜. 1 #include ...

  2. Oracle OCP 11g 常见单词(不定期更新)

    Oracle OCP 11g 常见单词(不定期更新) 数据库常见单词,不定期更新至考完ocp证(初步想法),现已收集807个单词: 最后一次更新时间为20180301. 1, ACCUMULATED  ...

  3. 【代码总结-不定期更新】

    [代码总结-不定期更新] 1 packagecom.runyi.share.service.information.commons.exceptions;2 3 importcom.runyi.ryp ...

  4. Android实用代码(不定期更新)

    Android实用代码七段(一) 一抹火焰 整理(不定期更新) 前言 这里积累了一些不常见确又很实用的代码,每收集7条更新一次,希望能对大家有用. 声明: 欢迎转载,但请保留文章原始出处:)  博客园 ...

  5. 【☀️不定期更新了⛅】感谢知识输出的正反馈

    不定期更新 最近沉迷写博,不能自拔.感谢知识输出的正反馈,又对知识学习燃起了激情.然而还是艰难地决定减少博客的时间投入,本地的技术总结markdown还是会继续写,博客可能不会每周定时发,以后可能就是 ...

  6. [刷题记录] luogu网络流24题 及 网络流心得体会 及 经典模型不定期更新

    文章目录 信息汇总表格 飞行员配对方案问题 分配问题 运输问题 数字梯形问题 最小路径覆盖问题 魔术球问题 圆桌问题 试题库问题 深海机器人问题 航空路线问题 火星探险问题 太空飞行计划问题 方格取数 ...

  7. React性能优化记录(不定期更新)

    React性能优化记录(不定期更新) 1. 使用PureComponent代替Component 在新建组件的时候需要继承Component会用到以下代码 import React,{Componen ...

  8. 区块链矿池(pool)汇总(不定期更新,欢迎评论区留言)

    文章目录 辅助类网站 大型综合类矿池 Bitcoin/Litcoin/zcash Monero 不定期更新 辅助类网站 矿池算例排行:https://miningpoolstats.stream/bi ...

  9. Liunx上训练模型的常见情况(不定期更新)

    这篇博客用来记录一些Linux上后台训练机器学习模型的时候可能用到的简短的代码(不定期更新) 目录: 后台执行python训练脚本 查看训练时占用的资源 中途停止模型的训练 1.后台执行python训 ...

  10. net core 小坑杂记之配置文件读取(不定期更新)

    其实很早就想写了,原想等积累差不多了再写的,但是发现遇到一个当时记下效果会比较好,所以就不定期更新这个系列了,后面获取会整个整理一下. 此篇记载net core入门时踩的一些坑,网上教程太少了,也不规 ...

最新文章

  1. xilinx FIFO
  2. Skype for business混合部署系列之二自定义拓扑信息
  3. Spring面试五连问,这怎么顶啊
  4. python输出日期的模版_python按日期区间生成markdown日记模板
  5. 【Visual Studio 扩展工具】使用 ComponentOne迷你图控件,进行可视化数据趋势分析...
  6. Atitit 实现java的linq 以及与stream api的比较
  7. Android中的Dialog
  8. 关于pipelineDB调用GetLocalStreamReaders的BUG
  9. jre放到Tomcat目录并指定使用此jre的方法
  10. python计算一定期间的涨幅_python数据分析与挖掘(十一)--- ndarray运算
  11. Windows上SVN服务器搭建【转】
  12. win 10 系统怎么显示隐藏文件
  13. eclipse中如何远程java debug配置
  14. Ajax Session Timeout处理
  15. 基于python的图书管理系统设计与实现论文_图书馆管理系统的设计与实现毕业论文...
  16. 紫色范冰冰WIN7主题包
  17. Python内置函数一览表
  18. python 读写pcd
  19. android 史上最简单behavior,安卓behavior详解1--系统behavior的简单应用
  20. 【数据结构与算法】栈与队列【C语言版】

热门文章

  1. 斯坦福大学自然语言处理第二课“文本处理基础(Basic Text Processing)”
  2. Reason of Random Initialization - Neural Networks
  3. 数字值太大,plsql显示不全的设置
  4. python必须知道的三个概念_关于python编码,你真的明白了吗
  5. java.util.function包下的四大Function
  6. 原生php phpmailer 发送邮件 email
  7. Web jsp开发学习——Servlet提交表单时用法
  8. SSM+Jedis初体验
  9. BZOJ——T 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
  10. 讲解浏览器 三次握手四次挥手。