题目链接:点击打开链接
题目大意:题意是两列在x=-100和x=100的战舰要攻击x=0处的两艘小的战舰。
如果左右两艘战舰和中间的小战舰在同一条直线时,激光攻击会贯穿而导致误伤,三艘战舰都死亡。
小战舰知道自己必死无疑,所以他要拉着更多的敌舰同归于尽。
两边的两列敌舰的坐标为整数,小战舰的纵坐标无要求可以是小数。
题目思路:因为两边的敌舰是关于小战舰所在的y轴对称,所以小战舰的位置与两边敌舰到x轴的截距有关。
如果不同的几组组合,他们到x轴的截距之和相同,那么小战舰放在截距和一半的位置上,就能将他们全部摧毁。
所以我们可以用状态压缩的思想,来记录小战舰在每个位置能摧毁哪些敌舰。
因为要计算两艘小战舰的共同摧毁的敌舰的数量,其中可能会有重复,所以需要用二进制存储然后用或(|)运算来计算,这时bitset就是一个很好的工具。
把每一个在y轴上的点的情况用状态压缩表示出来,再O(n2)枚举所有小飞船(t1,t2)的位置,用t1|t2就能O(1)求出大飞船被摧毁的数量。
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-10;
const int maxn=100+10;
int n,m;
int a[maxn],b[maxn];
bitset<65>tt1[50000],tt2[50000];
vector<int> v;
map<int,int>mp;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<m;i++)cin>>b[i];
bitset<65> *t1=tt1+25000,*t2=tt2+25000;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
t1[a[i]+b[j]][i]=1;
t2[a[i]+b[j]][j]=1;
if(!mp[a[i]+b[j]])
{
mp[a[i]+b[j]]=1;
v.push_back(a[i]+b[j]);
}
}
}
int mine=-1;
for(int i=0;i<v.size();i++)
{
for(int j=0;j<v.size();j++)
{
int sum=(t1[v[i]]|t1[v[j]]).count()+(t2[v[i]]|t2[v[j]]).count();
if(sum>mine)
mine=sum;
}
}
printf("%d\n",mine);
return 0;
}