D. Limak and Shooting Points 计算几何+模拟

来源:互联网 发布:博物馆文艺软件 编辑:程序博客网 时间:2024/06/08 15:28
D. Limak and Shooting Points
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Bearland is a dangerous place. Limak can’t travel on foot. Instead, he has k magic teleportation stones. Each stone can be used at most once. The i-th stone allows to teleport to a point (axi, ayi). Limak can use stones in any order.

There are n monsters in Bearland. The i-th of them stands at (mxi, myi).

The given k + n points are pairwise distinct.

After each teleportation, Limak can shoot an arrow in some direction. An arrow will hit the first monster in the chosen direction. Then, both an arrow and a monster disappear. It’s dangerous to stay in one place for long, so Limak can shoot only one arrow from one place.

A monster should be afraid if it’s possible that Limak will hit it. How many monsters should be afraid of Limak?

Input

The first line of the input contains two integers k and n (1 ≤ k ≤ 71 ≤ n ≤ 1000) — the number of stones and the number of monsters.

The i-th of following k lines contains two integers axi and ayi ( - 109 ≤ axi, ayi ≤ 109) — coordinates to which Limak can teleport using the i-th stone.

The i-th of last n lines contains two integers mxi and myi ( - 109 ≤ mxi, myi ≤ 109) — coordinates of the i-th monster.

The given k + n points are pairwise distinct.

Output

Print the number of monsters which should be afraid of Limak.

Examples
input
2 4-2 -14 54 22 14 -11 -1
output
3
input
3 810 200 020 40300 60030 60170 34050 10028 5690 180-4 -8-1 -2
output
5
Note

In the first sample, there are two stones and four monsters. Stones allow to teleport to points ( - 2,  - 1) and (4, 5), marked blue in the drawing below. Monsters are at (4, 2)(2, 1)(4,  - 1) and (1,  - 1), marked red. A monster at (4,  - 1) shouldn't be afraid because it's impossible that Limak will hit it with an arrow. Other three monsters can be hit and thus the answer is 3.

In the second sample, five monsters should be afraid. Safe monsters are those at (300, 600)(170, 340) and (90, 180).


——————————————————————

题意:有k个射击点,n只怪兽,每个射击点只能射击一次,且只能射击一条直线上的第一个没有死亡的怪兽,有多多少只怪兽是有可能会被打死的

题解:可以发现,如果开枪的顺序被确定,且都以打死一只怪兽为目标,那么这只怪兽可不可以被打死是可以模拟出来的(具体见代码)

发现k很小,可以用k!的复杂度来枚举所有的开枪顺序

然后枚举一个怪兽,但是发现我们还要枚举射击点和怪兽之间的怪兽  时间复杂度O(k!*n*n) 发现会TLE

预处理mp[i][j]表示第i个射击点和第j只怪兽为端点的线段间有哪些怪兽

时间复杂度优化到O(k*n*n+k!*n)


三点共线的判定:

判断A,B,C三点共线,则AB×BC=0

若B为中间点  则  AB·AC>0 CB·CA>0

后面一个点积的运用可以直接暴力判,这样方便一些

我傻。。代码里就暴力判了


#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<cstring>#define For(i,j,k)for(ll i=j;i<=k;++i)#define Dow(i,j,k)for(ll i=k;i>=j;--i)#define ll long longusing namespace std;inline ll read(){ll t=0,f=1;char c=getchar();while(c==' '||c=='\n')c=getchar();if(c=='-')f=-1,c=getchar();while(c<='9'&&c>='0')t=t*10+c-48,c=getchar();return t*f;}struct poi{ll x,y;} st[10],ms[2001];ll tim,k,n,gg[2001],que[10],alr,ans;vector<ll> mp[10][1101];bool vis[10];ll operator *(const poi &x,const poi &y){return x.x*y.y-x.y*y.x;}poi operator -(const poi &x,const poi &y){static poi tmp;tmp.x=x.x-y.x;tmp.y=x.y-y.y;return tmp;}ll operator ^(const poi &x,const poi &y){return x.x*y.x+x.y*y.y;}inline bool check(const poi &x,const poi &a,const poi &b){if((x-a)*(x-b)!=0)return 0;if(a.y==b.y)return (x.x)<max(a.x,b.x)&&(x.x)>min(a.x,b.x);else return (x.y)<max(a.y,b.y)&&(x.y)>min(a.y,b.y);}inline bool kill(ll x){alr++;if(alr==k+1)return 0;if(mp[que[alr]][x].empty()){gg[x]=tim;return 1;}ll gd=alr;for(ll i=0;i<mp[que[gd]][x].size();++i){ll t=mp[que[gd]][x][i];if(gg[t]!=tim)if(!kill(t))return 0;}gg[x]=tim;return 1;}inline bool dfs(ll to,ll x){if(x==k+1){alr=0;tim++;return kill(to);}bool flag=0;For(i,1,k){if(!vis[i]){vis[i]=1;que[x]=i;flag|=dfs(to,x+1);vis[i]=0;if(flag)return 1;}}return flag;}int  main(){k=read();n=read();For(i,1,k)st[i].x=read(),st[i].y=read();For(i,1,n)ms[i].x=read(),ms[i].y=read();For(i,1,k)For(j,1,n){For(k,1,n)if(k!=j&&check(ms[k],st[i],ms[j]))mp[i][j].push_back(k);}For(i,1,n){memset(vis,0,sizeof vis);if(dfs(i,1))ans++;}cout<<ans<<endl;}


原创粉丝点击