文章目录
二分法的简单应用
嘉馨学姐的超级幸运数字
这里的二分法主要是用来查找。
这个题目还使用到了预处理的方法。注意:预处理也会消耗时间,所以不要超过百万级别。
- 从所有的可能答案中找到需要的答案。
- 使用二分查找可以快速地在众多可能的答案中找到需要的答案。
- 下面为代码实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10000000;
ll num[N];
void init()
{
for(ll i=1; i<=N; i++){
num[i]=(i+1)*i/2;
}
}
int main()
{
ll n;
init();
while( scanf("%lld", &n)!=EOF)
{
int flag=0;
for(int i=1; i<=N; i++)
{
if(num[i]>=n){
break;
}
ll tmp=n-num[i];
/*
for(int j=i; j<=N; j++)
{
if(num[j]>tmp){
break;
}
if(num[j]==tmp){
flag=1;
break;
}
}
*/
//应该使用二分查找,避免超时
int begin=i, end=N;
while(begin<=end)
{
ll mid=(begin+end)/2;
if(num[mid]==tmp){
flag=1;
break;
}
if(num[mid]<tmp){
begin=mid+1;
}else end=mid-1;
}
if(flag==1) break;
}
if(flag==1){
printf("YES\n");
}else printf("NO\n");
}
return 0;
}
嘉馨学姐吃汉堡
- 首先这个题不能使用模拟的办法来进行解决,因为数据范围是1e12,超过了百万级别
- 这个可以使用二分查找法快速在答案集合中找到需要的答案
- 下面为代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll maxnum=1e12+100; //根据题目的输入要求,答案最多是这样
char str[105];
int nb, ns, nc;
int pb, ps, pc;
ll r;
int b=0, s=0, c=0;
bool judge(ll x)
{
ll sum=0;
if(x*b>nb){
sum=sum+pb*(x*b-nb);
if(sum>r){
return false;
}
}
if(x*s>ns){
sum=sum+ps*(x*s-ns);
if(sum>r){
return false;
}
}
if(x*c>nc){
sum=sum+pc*(x*c-nc);
if(sum>r){
return false;
}
}
return true;
}
int main()
{
while(scanf("%s", str)!=EOF)
{
b=0, s=0, c=0;
scanf("%d%d%d", &nb,&ns,&nc);
scanf("%d%d%d", &pb,&ps,&pc);
scanf("%lld", &r);
for(int i=0; str[i]!='\0'; i++)
{
if(str[i]=='B'){
b++; continue;
}else if(str[i]=='S'){
s++; continue;
}else c++;
}
ll ans=0;
// 使用模拟的方法会超时
/*
while(r>0)
{
if(b>nb){
nb=0;
ll tmp=b-nb;
r-=tmp*pb;
if(r<0) {
break;
}
}else nb-=b;
if(s>ns){
ns=0;
ll tmp=s-ns;
r-=tmp*ps;
if(r<0){
break;
}
}else ns-=c;
if(c>nc){
nc=0;
ll tmp=c-nc;
r-=tmp*pc;
if(r<0){
break;
}
}else nc-=c;
ans++;
}
*/
ans=0;
ll begin=0, end=maxnum;
while(begin<=end)
{
ll mid=(begin+end)/2;
if(judge(mid)){
ans=mid;
begin=mid+1;
}else end=mid-1;
}
printf("%lld\n", ans);
}
return 0;
}