容斥原理(二分+排序)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4155

题目大意:寻找两个圆的交集部分的点的个数c1,之后再寻找圆外面的点的个数c2。如果c2<c1则输出0,否则输出c2-c1

解题思路:

这个题目如果纯粹的暴力肯定是超时(别尝试了,我已经暴了N遍了,还是TLE)。关键还是优化算法,利用容斥原理+二分+排序

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#define maxn 200000+10
using namespace std;
#ifdef __int64
typedef __int64 LL;
#else
typedef long long LL;
#endif
int v[maxn][2];
double d1[maxn],d2[maxn];//保存每个点到两个圆的圆心的距离
int bs(double s[],int l,int h,int v)//二分查找,找出在圆内有多少个点
{
    while(l<h)
    {
        int m=(l+h)>>1;
        if(s[m]<=v)
        {
            l=m+1;
        }
        else
        {
            h=m;
        }
    }
    return l;
}
int main()
{
    int t,ncase=1;
    while(scanf("%d",&t)&&t)
    {
        printf("Case %d:\n",ncase++);
        for(int i=0;i<t;i++)
        {
            scanf("%d%d",&v[i][0],&v[i][1]);
        }
        int x1,y1,x2,y2,q;
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&q);
        for(int i=0;i<t;i++)
        {
            d1[i]=(double)sqrt((v[i][0]-x1)*(v[i][0]-x1)+(v[i][1]-y1)*(v[i][1]-y1));
            d2[i]=(double)sqrt((v[i][0]-x2)*(v[i][0]-x2)+(v[i][1]-y2)*(v[i][1]-y2));
        }
        sort(d1,d1+t);
        sort(d2,d2+t);
        int c1,c2;
        while(q--)
        {
            double a,b;
            scanf("%lf%lf",&a,&b);
            c1=bs(d1,0,t-1,a);//printf("c1=%d\n",c1);
            c2=bs(d2,0,t-1,b);//printf("c2=%d\n",c2);
            if(t-c1-c2<=0)
                printf("0\n");
            else
                printf("%d\n",t-c1-c2);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
容斥原理是一种计数方法,用于解决集合中某些对象的数目的问题。它的基本思想是先计算包含于某个内容中的所有对象的数目,然后排除重复计算的对象,以确保计数结果既不遗漏又没有重复。在容斥原理的应用中,通常需要先求出所有包含的区间,然后使用欧拉函数求和,并进行一些补充操作,例如乘以某个系数或减去一个常数。在使用容斥原理时,需要注意一些细节,例如在枚举因子时要注意使用最小公倍数(LCM),而不是直接相乘。如果容斥问题中的集合可能包含0,还需要特殊处理。至于如何使用容斥原理在MATLAB中求解具体的问题,我需要更多的上下文信息才能给出具体的指导。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [容斥原理](https://blog.csdn.net/ling_wang/article/details/80488797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [容斥原理练习记录](https://blog.csdn.net/z631681297/article/details/81318279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值