m皇后(思路題目)

這道題當初有兩點沒有想到,一點是不知道該如何處理斜着的方向,另一點是沒想到只用求該直線上的兩端點。

這題要開四個數組,分別記錄該方向上的點的最左端和最右端。
然後遍歷所有的點,遍歷該點的四個方向(上下是一個方向,左右是一個方向,斜向上一個,斜向下一個),如果該方向上只有一個點,就不存在威脅,如果該點在最右端或者最左端,在該方向上就有一個威脅,否則該點在中間,就有兩個威脅。然後記錄該點有幾個威脅。

忘了一點,如何判斷斜方向的範圍:
斜方向的斜率都是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;
}
發佈了186 篇原創文章 · 獲贊 14 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章