四平方和
首先考虑时间复杂度 每一个数的范围都在0~2200之间
最多只能枚举两个数,考虑用空间换时间。
先试着用最基础的三重循环:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2500010;
int n;
int main()
{
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-a*a-b*b-c*c;
int d=sqrt(t);
if (d*d==t)
{
printf("%d %d %d %d\n",a,b,c,d);
return 0;
}
}
}
虽然是可行的,但是超时了。
所以开始采用二分:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2500010;
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];
int n,m;
int main()
{
cin>>n;
//按照字典序枚举c、d组合
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=0;a*a+b*b<=n;b++)
{
int t=n-a*a-b*b; //差值
int l=0,r=m-1;
while(l<r)
{
int mid =l+r>>1;
if(sum[mid].s>=t) r=mid;
else l=mid+1;
}
if(sum[l].s==t)
{
printf("%d %d %d %d\n",a,b,sum[l].c,sum[l].d);
return 0;
}
}
return 0;
}
哈希表做法(暂时不会):
分巧克力
对于每一块巧克力来说,它能切出来的块数是随着边长的增大而递减的,边长越大,块数越小。
找到一个满足块数大于等于K的最大的一个点
if (f(mid)≥k) L=mid;else R=mid-1;
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int n,k;
int h[N],w[N];
bool check(int mid)
{
int res=0;//最多能分多少块
for(int i=0;i<n;i++)
{
res=res+(h[i]/mid)*(w[i]/mid);
if(res>=k) return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++) scanf("%d%d",&h[i],&w[i]);//读取每一块巧克力初始长度
int l=1;//每一个小朋友至少获得一块1x1的巧克力,所以最小为1
int r=1e5;
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",r);
return 0;
}