首页 > 其他分享 >回顾二分答案 例题分析(D. Fast and Fat 和 I.Path Planning)

回顾二分答案 例题分析(D. Fast and Fat 和 I.Path Planning)

时间:2024-05-28 09:30:41浏览次数:27  
标签:二分 return int mid Fast Planning 答案 例题 define

对于二分答案的引述来自:二分查找 & 二分答案 万字详解,超多例题,带你学透二分。_c++二分答案怎么确定是l<r还是l<=r-CSDN博客

概念:

二分答案:答案有一个区间,在这个区间中二分,直到找到最优答案。


什么时候用二分答案?

答案属于一个区间,当这个区间很大时,暴力超时。但重要的是——这个区间是对题目中的某个量有单调性的,此时,我们就会二分答案。每一次二分会做一次判断,看是否对应的那个量达到了需要的大小。

如何判断一个题是不是用二分答案做的呢?
  1. 答案在一个区间内(一般情况下,区间会很大,暴力超时)
  2. 直接搜索不好搜,但是容易判断一个答案可行不可行
  3. 该区间对题目具有单调性,即:在区间中的值越大或越小,题目中的某个量对应增加或减少

此外,可能还会有一个典型的特征求...最大值的最小 、 求...最小值的最大。

  1. 求...最大值的最小,我们二分答案(即二分最大值)的时候,判断条件满足后,尽量让答案往前来(即:让r=mid)
  2. 同样,求...最小值的最大时,我们二分答案(即二分最小值)的时候,判断条件满足后,尽量让答案往后走(即:让l=mid)

基于上述思想,来看两道去年XCPC的二分答案的例题。

写在前面:最近这两次训练赛都没看出这是一道二分答案的题,导致这两题都卡了挺久(主要还是连思路都不对),所以回头总结一下二分答案可能的情况,为下次遇到新题时能更快想到二分答案的思路。


The 13th Shandong ICPC Provincial Collegiate Programming Contest

里面的D题   题目链接:Problem - D - Codeforces

题意:对于一个运动员 i ,他的速度是 vi,体重是 wi。如果运动员 j 的体重 wj <= wi,那么运动员 i 可以用原本的速度 vi 背着运动员 j 奔跑。如果 wj > wi,那么速度就变成了 vi - ( wi - wj ) (如果是负数,那么运动员 i 不能背着 j 奔跑),求这个团队奔跑起来后速度最慢的那个人的速度最大值。​​​​​​

思路:求·····最小值的最大,那么我们可以考虑二分答案,套用二分求右边界的模板,重点是如何写check函数,我们可以开两个数组,一个用来存入被背的人数,一个用来存入背别人的人数,被背的人的数组存的是该人的体重,背别人的数组存的是vi+wi-x(x是二分的数,公式由来x=vi+wi-wj),将这两个数组进行降序排序,然后进行比较即可。

代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=1e5+5;
struct node{
	int a,b;
};
node s[N];
int n;
bool cmp1(int x,int y){
	return x>y;
}
bool cmp2(int x,int y){
	return x>y;
}
bool check(int x){
	vector<int> b;//存入被背的人的数量
	vector<int> c;//存入背别人的人的数量
	for(int i=0;i<n;++i){
		if(s[i].a<x){
			b.push_back(s[i].b);
		}
		else c.push_back(s[i].a+s[i].b-x);
	}
	int lenb=b.size(),lenc=c.size();
	if(lenb>lenc) return false;
	sort(b.begin(),b.end(),cmp1);
	sort(c.begin(),c.end(),cmp2);
	for(int i=0;i<lenb;++i){
		if(b[i]>c[i]) return false;//当背不下时直接返回flase
	}
	return true;//全背的下返回true
}
void solve(){
	cin >> n;
	int l=0,r=0;
	for(int i=0;i<n;++i){
		cin >> s[i].a >> s[i].b;
		r=max(r,s[i].a);
	}
	r+=1;
	while(l<r){//二分求右边界模板
		int mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	}
	cout << l << endl;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	cin >> t;
	while(t--) solve();
	return 0;
}

The 2023 Guangdong Provincial Collegiate Programming Contest

里面的I题  题目链接:Problem - I - Codeforces

题意:

思路:题目求所有mex(S)的最小非负整数中最大的mex(S),也是和上题一样求····最小值的最大,那么我们也是考虑二分答案,首先看数据范围,我们首先需要状态压缩,由题意可知右边界最大为n*m,同样套用二分求右边界模板,在check函数里面,由题目(i,j)的状态转移只能是向下或者向右,那么我们可以用一个变量k来标记下标,当x(即二分的数)大于a[i][j]时,若k大于j,直接返回false(因为它只能向下或者向右走,那么每次移动的过程不能回头,k即是模拟它当前的下标),若小于等于j更新k等于j,最后若循环结束直接返回true即可。

代码:

#include<bits/stdc++.h>
#define int long long 
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int> 
using namespace std;
const int N=1e6+5;
int a[N];
int n,m;
bool check(int x){
	int k=0;//标记棋子移动的下标
	for(int i=0;i<n;++i)
	   for(int j=0;j<m;++j){
	   	if(a[i*m+j]<x){//若小于x则需要状态转移
	   		if(k>j) return false;//若k大于j则不满足题意
	   		k=j;
		   }
	   }
	return true;
}
void solve(){
	cin >> n >> m;
	for(int i=0;i<n;++i)
	   for(int j=0;j<m;++j){
	   	cin >> a[i*m+j];//状态压缩
	   }
	int l=0,r=n*m;
	while(l<r){
		int mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else r=mid-1; 
	}
	cout << l << endl;
	return ;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int t=1;
	cin >> t;
	while(t--) solve();
	return 0;
}

标签:二分,return,int,mid,Fast,Planning,答案,例题,define
From: https://blog.csdn.net/wh233z/article/details/139244348

相关文章

  • FEL - Fast Expression Language
    开源好用的表达式计算语言FEL,可惜了官网文档不在国内,我来个过来。Fel是轻量级的高效的表达式计算引擎Fel在源自于企业项目,设计目标是为了满足不断变化的功能需求和性能需求。Fel是开放的,引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是F......
  • 算法刷题笔记 数的范围(C++实现)(二分法重要例题)
    文章目录题目描述题目思路题目代码(C++)题目感想题目描述给定一个按照升序排列的长度为n的整数数组,以及q个查询。对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。如果数组中不存在该元素,则返回-1-1。输入格式:第一行包含整数n和q,表示数组长度和询......
  • Python中Web开发-FastAPI框架
            大家好,在当今Web开发领域,高性能、易用性和可扩展性是开发者们追求的目标。Python作为一种流行的编程语言,在Web开发领域也有着强大的影响力。而在众多的PythonWeb框架中,FastAPI凭借其快速、现代和易用的特性,成为了开发者们的首选之一。本文将深入探讨FastAPI......
  • Python & FastAPI , 路径(路由)操作
    路径,或称“端点”或“路由”/items/foo=>指向的路径为:https://www.xxx.com/items/foo在HTTP协议中,可以使用这些“方法”中的一个(或多个)与每个路径通信:HTTP方法:POST,GET,PUT,DELETE,OPTIONS,HEAD,PATCH,TRACE在构建api时,通常使用这些特定的HTTP方法来执行特定......
  • Python & FastAPI , 路径中带参数
    如下:fromfastapiimportFastAPIapp=FastAPI()@app.get("/items/{item_id}")asyncdefread_item(item_id):return{"item_id":item_id}路径参数item_id的值将作为参数item_id传递给函数,输入http://127.0.0.1:8000/items/foo,foo为传入的参数,则其响应如下:{"it......
  • 【每周例题】力扣 C++ 字符串相乘
    字符串相乘题目字符串相乘题目分析1.首先,题目上标出了一条:注意:不能使用任何内置的BigInteger库或直接将输入转换为整数。这就是这道题的难度所在2.这样子的话,我们可以从手写乘法计算来寻找思路: ①首先我们需要将各位相乘的结果放入数组ansArr中,我们使用双重for循环计算......
  • 【全开源】多场馆场地预定小程序源码(ThinkPHP+FastAdmin+UniApp)
    场馆场地预定小程序源码一款基于ThinkPHP+FastAdmin+UniApp开发的多场馆场地预定小程序,提供运动场馆运营解决方案,适用于体育馆、羽毛球馆、兵乒球馆、篮球馆、网球馆等场馆(高级版)......
  • 线段树维护区间字符的两道例题(CF240F CF558E)
    CF240F:https://www.luogu.com.cn/problem/CF240F题目大意:给定一个长为n的由a到z组成的字符串,有m次操作,每次操作将[l,r]的字符串进行重排,得到字典序最小的字符串,输出m次操作后的字符串。大致思路:1.首先我们要想区间内的字典序最小的回文串要怎么构造。回文串无非就两种类型:有一......
  • 状压dp 例题
    终于在洛谷上发布题解了QWQP10447最短Hamilton路径题解分析题目:一张nnn个点的带权无向图,求起点0......
  • Python案例题目,入门小白题
    1.抓取链家前十页的数据链家网址:长沙房产网_长沙房地产_长沙房产门户(长沙链家网)1.1.计算均价和总价importtime​fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy​driver=webdriver.Chrome()driver.get("https://cs.lianjia.com/zu......