提示:以下是本篇文章正文内容,下面案例可供参考
十四届蓝桥杯C/C++b组试题C冶炼金属
试题
1.二分法使用两个模板
/**
* 普通金属O-->特殊金属X
* 转换率V: 消耗V个普通金属可以-->一个特殊金属X
* 现在给出了 N条冶炼记录,每条记录中包含两个整数 A和 B
* 表示 A个普通金属 生产出了B个特殊金属
* 推测出转换率 V的最小值和最大值分别可能是多少
*
*/
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+10;
const int MAX = 1e9;
//用数组表示投入的a金属和生产特殊b金属
//b[i]表示第i次炼金时候炼出来的b金属数量
//a[i]表示第i次炼金时候投入的a金属数量
int a[N];
int b[N];
int n;
int check(int val)
{
for(int i =0;i<n;i++)
{
if(a[i]/val>b[i]) return 2;//说明val值小了
if(a[i]/val<b[i]) return 3;//说明val值大了
}
return 1;
}
int main()
{
cin>>n;
for(int i =0;i<n;i++){
cin>>a[i]>>b[i];
}
//找V的最小值
int l = 1,r=MAX;
while (l<r)
{
int mid = l+r>>1;
int mark = check(mid);
//寻找最小值 说明mid值大 我们需要在小一点
if(mark == 1|| mark ==3) r = mid;
else l =mid+1;
}
cout<< r <<" ";
//找V的最大值
l = 1,r=MAX;
while (l<r)
{
int mid = l+r+1>>1;
int mark = check(mid);
//寻找最大值 说明mid值小 我们需要在大一点
if(mark == 1|| mark ==2) l=mid;
else r = mid-1;
}
cout<< r <<endl;
return 0;
}
2.二分法使用一个模板
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int Binary_Search(int a,int b)
{
int l = 1,r =1e9+1;
while(l<r)
{
int mid = l+r>>1;
if(a/mid<=b) r = mid;
else l =mid+1;
}
}
int main()
{
int n;
cin>>n;
int v_min = 1,v_max=1e9;
while(n--)
{
int a,b;
cin >> a >>b;
v_min = max(v_min,Binary_Search(a,b));
v_max = min(v_max,Binary_Search(a,b-1)-1);
}
cout<<v_min<<' '<<v_max<<endl;
return 0;
}
3.数学推导公式方法
**
*
* 数学推导公式做法
* A/V(向下取整)=B
* 可以最终推导为 A/(B+1)<V<=A/B
* 所以Vmax就为A/B(向下取整) Vmin为A/(B+1)(向下取整)+1
*/
#include<bits/stdc++.h>
using namespace std;
int Vmin = 0;
int Vmax = 2e9;
int main()
{
int n;
int a,b;
cin>>n;
while (n--)
{
cin >> a >> b;
Vmin = min(Vmax,a/(b+1)+1);
Vmax = max(Vmin,a/b);
}
cout << Vmin<<' '<<Vmax<<endl;
return 0;
}