這道題當初有兩點沒有想到,一點是不知道該如何處理斜着的方向,另一點是沒想到只用求該直線上的兩端點。
這題要開四個數組,分別記錄該方向上的點的最左端和最右端。
然後遍歷所有的點,遍歷該點的四個方向(上下是一個方向,左右是一個方向,斜向上一個,斜向下一個),如果該方向上只有一個點,就不存在威脅,如果該點在最右端或者最左端,在該方向上就有一個威脅,否則該點在中間,就有兩個威脅。然後記錄該點有幾個威脅。
忘了一點,如何判斷斜方向的範圍:
斜方向的斜率都是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;
}