1612: 劉備闖三國之桃園結義
Time Limit: 1000 MS Memory Limit: 128 MBSubmit: 181 Solved: 12
[Submit][Status][Web Board]
Description
劉備(161年-223年6月10日),字玄德,東漢末年幽州涿郡涿縣,西漢中山靖王劉勝的後代。劉備一生極具傳奇色彩,早年顛沛流離、備嘗艱辛最終卻憑藉自己的謀略終成一方霸主。那麼在那個風雲激盪的年代,劉備又是如何從一個賣草鞋的小人物一步一步成爲蜀漢的開國皇帝呢?讓我們一起撥開歷史的迷霧,還原一個真實的劉備。
劉備心懷大志,當然不甘於當一個賣草鞋的小販,於是離家闖蕩江湖。恰好遇到志同道合的關羽、張飛二人,三人準備在桃園結義。但是在誰當大哥的問題上,關張並不服劉備當老大,二人環顧四周,靈機一動,給劉備提出如下問題:
當時的桃園遊人摩肩接踵、然而春雨綿綿。桃園內有n個行人,和m個亭子,有些遊客在亭子內躲雨,但也有一些行人在雨中漫步。關張表示:如果劉備能準確統計出有多少個人在雨中,那他們就認劉備當大哥。桃園可以看出二維平面座標軸,行人爲點,亭子爲圓形。
劉備微微一笑,左顧右盼、前瞻後顧,然而算得頭昏腦脹。做爲劉備身邊的小弟,又到了你替老大分擔憂愁的時候了。
Input
第一行一個整數n(1<=n<=10^5),表示有n個行人
以下有n行,每行有n有兩個整數x,y (0<=x,y<=10000),表示行人的座標爲(x,y)
接下來有一個整數m(1<=m<=20000),表示桃園中有m個亭子,亭子可以視爲圓形。
以下m行,每行有3個整數x ,y ,r ,(0<=x,y<=10000, 1<=r<=100)表示亭子的中心座標爲(x,y),半徑爲r,亭子之間可以相交。
Output
輸出在雨中行人的個數。
如果行人在亭子的邊緣位置,也記爲在亭子內。
Sample Input
0 0
100 0
0 100
100 100
50 50
1
0 0 50
Sample Output
HINT
Source
題目鏈接:
http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1612
題目大意:
圖上有N個點,M個圓,圓可能相交,問N個點中不被任何圓覆蓋到的點有多少個。
題目思路:
【二分】
首先將點按x座標從小到大排序,再將圓按照x+r從小到大排序
之後枚舉每一個點,二分找到第一個x座標包含到當前點x座標的圓,之後開始往後判斷,是否被圓覆蓋。只要一被覆蓋就break
/****************************************************
Author : Coolxxx
Copyright 2017 by Coolxxx. All rights reserved.
BLOG : http://blog.csdn.net/u010568270
****************************************************/
#include<bits/stdc++.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define mem(a,b) memset(a,b,sizeof(a))
const double EPS=1e-8;
const int J=10;
const int MOD=100000007;
const int MAX=0x7f7f7f7f;
const double PI=3.14159265358979323;
const int N=100004;
const int M=20004;
using namespace std;
typedef long long LL;
double anss;
LL aans;
int cas,cass;
int n,m,lll,ans;
bool in[N];
struct Point
{
int x,y;
}p[N];
struct Circle
{
int x,y,r;
}c[M];
bool cmp1(Point a,Point b)
{
if(a.x!=b.x)return a.x<b.x;
return a.y<b.y;
}
bool cmp2(Circle a,Circle b)
{
if((a.x+a.r)!=(b.x+b.r))return (a.x+a.r)<(b.x+b.r);
return a.r>b.r;
}
inline int dis(Point a,Circle b)
{
return sqr(a.x-b.x)+sqr(a.y-b.y);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif
int i,j,k;
int x,y,z;
// for(scanf("%d",&cass);cass;cass--)
// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
// while(~scanf("%s",s))
while(~scanf("%d",&n))
{
ans=n;
for(i=1;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p+1,p+1+n,cmp1);
scanf("%d",&m);
for(i=1;i<=m;i++)
scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r);
sort(c+1,c+1+m,cmp2);
int last=1;
for(i=1;i<=n;i++)
{
int l,r,mid;
l=last;r=m;
while(l<r)
{
mid=(l+r)/2;
if(c[mid].x+c[mid].r>=p[i].x)r=mid;
else l=mid+1;
}
last=l;
for(j=mid;j<=m;j++)
{
if(dis(p[i],c[j])<=sqr(c[j].r))
{
ans--;
break;
}
if(c[j].x-c[j].r>p[i].x)break;
}
}
printf("%d\n",ans);
}
return 0;
}
/*
//
//
*/