版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/82735449
题目链接<http://codeforces.com/contest/1041/problem/F>
题意:
在两个反射面上取一点发射一道激光,两个反射面上装了一些传感器,问最多有几个传感器能接收到激光。
题解:
首先,题目给出了反射面的纵坐标,这是没有用的,我们只需要考虑横坐标的距离即可。
然后总体思路是:
1)枚举步长。
2)处理出每个点在此步长下的状态,并用map记录每个状态的数量。
3)再枚举起点(起点只需枚举传感器的位置)计算每个起点下的答案。
后面两个复杂度是在1e5级别的,而第一个的复杂度能够达到1e9。
仔细推敲或者参考题解后就可以发现,步长只需枚举的情况,这样复杂度可以降到30。
简单证明一下,如果步长不是,那么步长可以化为的形式,很容易发现前者是包含后者的,如果在图上进行模拟的话会更清晰。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+7;
int n,m,y,a[N],b[N];
map<int,int>aa,bb;
int main(){
scanf("%d%d",&n,&y);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d%d",&m,&y);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
int ans=0;
if(n) ans++;if(m) ans++;
int mod=2;
for(int k=2;k<=30;k++){
aa.clear(),bb.clear();
for(int i=1;i<=n;i++)
aa[a[i]%mod]++;
for(int i=1;i<=m;i++)
bb[b[i]%mod]++;
for(int i=1;i<=n;i++)
ans=max(ans,aa[a[i]%mod]+bb[(a[i]%mod+mod/2)%mod]);
for(int i=1;i<=m;i++)
ans=max(ans,bb[b[i]%mod]+aa[(b[i]%mod+mod/2)%mod]);
mod*=2;
}
printf("%d\n",ans);
return 0;
}