Acwing 730. 机器人跳跃问题
解题思路
理解过程中E的变化
不管E是否大于h,始终E1=2E0-h(0)
然后把这个作为二分判断是否通过的遍历依据,查找出目标值
*E<0说明不是这个值可以直接return
*E>1e5,前面一次超过1e5后面每一次都会超过
因为2E-h的最大值依旧大于1e5,这样可以节省运行次数
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int H[N];
bool is_correct(int E,int n){
//判定数值是否符合选择标准
for(int i=0;i<n;i++){
E=2*E- H[i];
if(E<0) return false;
//如果前面一次超过1e5,后面每次都必定会超过,但是往复几次会超出int范围
if(E > 1e5) return true;
}
return true;
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++)cin>>H[i];
int l=0,r=1e5;
while(l<r){
int mid=(l+r)/2;
if(is_correct (mid,n) ){
r=mid;
}else{
l=mid+1;
}
}
cout<<l<<endl;
return 0;
}
Acwing 1221. 四平方和

解题思路
1.三层循环暴力枚举,时间复杂度较高
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int n;
cin>>n;
for(int a=0;a*a<=n;a++)
for(int b=a;a*a+b*b<=n;b++)
for(int c=b;a*a+b*b+c*c<=n;c++){
int t=n-c*c-b*b-a*a;
int d=sqrt(t);
if(d*d==t){
cout<<a<<" "<< b<<" "<<c<<" "<<d;
return 0;
}
}
return 0;
}
2.用空间换时间,把c和d的枚举结果提前储存在数组中,然后在枚举a和b,把他们剩下的部分,使用二分或者哈希找出合适的值(使用二分要提前把数组sort,但是因为是使用结构体储存,要重载运算符来让sort正常使用)
一般cpu计算速度为1e8/s,所有可以提前对时间进行估算
a^2+b^2<N 这里的时间复杂度为n,因为可看作ΠR^2=N,R=N^1/2
加上二分的logN,为NlogN
#include<iostream>
#include<algorithm>
using namespace std;
const int N=5e6+10;
struct Sum{
int s,c,d;
bool operator <(const Sum& t)const{
if(s!=t.s)return s<t.s;
if(c!=t.c)return c<t.c;
return d<t.d;
}
}sum[N*2];
//用空间换时间,先把c,d的所有可能储存在数组里面后排序
//然后再遍历a,b 获得差值后,与数组里的数据进行对照,用二分On(logn或者哈希On(1)
//最后算法复杂度 On(n^2 * logn)
int main(){
int n,m=0;
cin>>n;
for(int c=0;c*c<=n;c++)
for(int d=c;c*c+d*d<=n;d++){
sum[m++]={c*c+d*d,c,d};
}
sort(sum,sum+m);
for(int a=0;a*a<=n;a++)
for(int b=a;a*a+b*b<=n;b++){
int t=n-a*a-b*b;
int l=0,r=m-1,mid;
while(l<r){
mid=(l+r)>>1;
if(t<=sum[mid].s)r=mid;
else l=mid+1;
}
if(t==sum[l].s){
cout<<a<<" "<<b<<" "<<sum[l].c<<" "<<sum[l].d;
return 0;
}
}
return 0;
}
1121

被折叠的 条评论
为什么被折叠?



