Codeforces #488div.2 - 994E - Careful Maneuvering(状态压缩+枚举)

题目链接:点击打开链接

题目大意:题意是两列在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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值