我的第一场,虽然是教育厂,但还是留下做个纪念把
第二题,给出n个数,求两数之和是2的幂次方的数对个数
:这题最后想出了map,但是感觉自己弱到爆了,map用的方法不对,wa。。。。
(这题我本来想卡时卡过去,可十万的数据范围直接不可能,一万都不好卡,100000根本不行,毕竟两层循环在那里了)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
int n,a[100005],b[100005],num[100005];
map<int,int> mp;
int main()
{
scanf("%d",&n);
int x;
long long ans=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&x);
for (int j=1;j<=30;j++) ans+=mp[(1ll<<j)-x];//因为2的次幂就那么多,枚举次幂,判断是否出现过,和出现了几次,这用map就很好办
mp[x]++;//把现在这个数加入到map中,供以后计算对数
}
printf("%I64d",ans);
return 0;
}
刚刚突然发现,原先的代码只要爆mp【x】--;提到上面来就能过。。。
因为一个数不能和自己组合,而前面的数已经和他配对过,所以到它时只需用在意他后面的数,他自己也不能算
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
int n,a[100005],b[100005],num[100005];
map<int,int> mp;
int main()
{
scanf("%d",&n);
int x;
for (int i=1;i<=n;i++) scanf("%d",&b[i]),mp[b[i]]++;
long long ans=0;
for (int i=1;i<=n;i++)
{
mp[b[i]]--;
for (int j=1;j<=30;j++)
ans+=mp[(1<<j)-b[i]];
}
printf("%I64d",ans);
return 0;
}
第三题:
给定数轴上n个city(点),和m个cellular network tower的点
求最小的半径,使得tower的信号可以覆盖所有city
n<=1e5;
显然二分。。。同时,只要数据范围差不多到int的极限了(1e9) 那么就要开 long long!!,反正多耗不了多少内存
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
int n,m;
ll a[100005],b[100005];
bool ok(ll mid)
{
int j=1;
for (int i=1;i<=n;)
{
if (abs(b[j]-a[i])<=mid) {i++;continue;}
if (a[i]<b[j])
return false;
else
{
j++;
if (j>m) return false;
}
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) scanf("%I64d",&a[i]);
for (int i=1;i<=m;i++) scanf("%I64d",&b[i]);
ll l=0,r=2*1e9,mid,ans=0;
while (l<=r)
{
mid=(l+r)>>1;
if (ok(mid)) {ans=mid;r=mid-1;}
else l=mid+1;
}
printf("%I64d",ans);
return 0;
}