这道题当初有两点没有想到,一点是不知道该如何处理斜着的方向,另一点是没想到只用求该直线上的两端点。
这题要开四个数组,分别记录该方向上的点的最左端和最右端。
然后遍历所有的点,遍历该点的四个方向(上下是一个方向,左右是一个方向,斜向上一个,斜向下一个),如果该方向上只有一个点,就不存在威胁,如果该点在最右端或者最左端,在该方向上就有一个威胁,否则该点在中间,就有两个威胁。然后记录该点有几个威胁。
忘了一点,如何判断斜方向的范围:
斜方向的斜率都是1或者-1,所以都满足y=x+b(或者y=-x+b),这样同一斜线上的y-x(或者y+x)的值是固定的,b就是判断条件,只需注意y-x为负数的时候就行了。
思想:
记录四个方向的点的分布范围(左右最值);
遍历每个点判断每个点的威胁个数。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=100009;
int xx[maxn][2];//以行为直线,纵坐标的分布,xx[][0]为最小值,xx[][1]为最大值,
int yy[maxn][2];//以列为直线,横坐标的分布,
int yx[maxn*2][2];//y=-x+b的直线的点的分布,
int y_x[maxn][4];//y=x+b的直线的点的分布,0,1记录y-x为正的最小值和最大值,2,3记录y-x为负的最小值和最大值
int ans[10];//ans[i]记录i个威胁的点的个数
int a[maxn],b[maxn];//记录横纵坐标
int main()
{
int n,m,x,y;
while(~scanf("%d%d",&n,&m))
{
memset(ans,0,sizeof(ans));//初始化
memset(xx,0,sizeof(xx));
memset(yy,0,sizeof(yy));
memset(yx,0,sizeof(yx));
memset(y_x,0,sizeof(y_x));
for(int i=0; i<m; i++)
{
scanf("%d%d",&x,&y);
a[i]=x,b[i]=y;
if(xx[x][0]==0)//以行为直线
xx[x][0]=xx[x][1]=y;
else
{
xx[x][0]=min(xx[x][0],y);
xx[x][1]=max(xx[x][1],y);
}
if(yy[y][0]==0)//以列为直线
yy[y][0]=yy[y][1]=x;
else
{
yy[y][0]=min(yy[y][0],x);
yy[y][1]=max(yy[y][1],x);
}
int f1=y+x;
int f2=y-x;
if(yx[f1][0]==0)//以y=-x+b为直线
yx[f1][0]=yx[f1][1]=y;
else
{
yx[f1][0]=min(yx[f1][0],y);
yx[f1][1]=max(yx[f1][1],y);
}
if(f2>=0)//以y=x+b为直线,且y-x>=0时
{
if(y_x[f2][0]==0)
y_x[f2][0]=y_x[f2][1]=y;
else
{
y_x[f2][0]=min(y_x[f2][0],y);
y_x[f2][1]=max(y_x[f2][1],y);
}
}
else
{
f2=-f2;
if(y_x[f2][2]==0)
y_x[f2][2]=y_x[f2][3]=y;
else
{
y_x[f2][2]=min(y_x[f2][2],y);
y_x[f2][3]=max(y_x[f2][3],y);
}
}
}
for(int i=0; i<m; i++)
{
int sum=0;
x=a[i],y=b[i];
int f1=x+y,f2=y-x;
if(xx[x][0]==xx[x][1]);//横向
else if(xx[x][0]==y||xx[x][1]==y)
sum++;
else sum+=2;
if(yy[y][0]==yy[y][1]);//纵向
else if(yy[y][0]==x||yy[y][1]==x)
sum++;
else sum+=2;
if(yx[f1][0]==yx[f1][1]);//斜向下
else if(yx[f1][0]==y||yx[f1][1]==y)
sum++;
else sum+=2;
if(f2>=0)//斜向上
{
if(y_x[f2][0]==y_x[f2][1]);
else if(y_x[f2][0]==y||y_x[f2][1]==y)
sum++;
else sum+=2;
}
else
{
f2=-f2;
if(y_x[f2][2]==y_x[f2][3]);
else if(y_x[f2][2]==y||y_x[f2][3]==y)
sum++;
else sum+=2;
}
ans[sum]++;//个数加一
}
for(int i=0; i<8; i++)//输出
printf("%d ",ans[i]);
printf("%d\n",ans[8]);
}
return 0;
}