Newcoder 70 F.m皇后(水~)
阿新 • • 發佈:2018-12-16
Description
在一個的國際象棋棋盤上有個皇后。
一個皇后可以攻擊其他八個方向的皇后(上、下、左、右、左上、右上、左下、右下)。
對於某個皇后,如果某一個方向上有其他皇后,那麼這個方向對她就是不安全的。
對於每個皇后,我們都能知道她在幾個方向上是不安全的。
現在我們想要求出,其中表示恰有個方向是"不安全的"的皇后有多少個。
Input
第一行兩個整數表示棋盤大小和皇后數量。
接下來行每行兩個整數表示皇后座標。
資料保證沒有皇后在同一個位置上。
Output
一行九個整數表示答案。
空格隔開,結尾無空格
Sample Input
8 4 4 3 4 8 6 5 1 6
Sample Output
0 3 0 1 0 0 0 0 0
Solution
以橫向為例,把個點按橫座標為第一關鍵字,縱座標為第二關鍵字排序,如果一個點前有橫座標與其相同的點,那麼左邊就不安全,如果該點後有橫座標與其相同的點,那麼右邊就不安全
縱向,以縱座標為第一關鍵字,橫座標為第二關鍵字
對角線方向,以橫縱座標差為第一關鍵字,橫座標為第二關鍵字
斜對角線方向,以恆做座標和為第一關鍵字,橫座標為第二關鍵字
如此統計出一個點的不安全方向即可,時間複雜度
Code
#include<cstdio> #include<algorithm> using namespace std; const int maxn=100005; int n,m,ans[maxn],num[10]; struct node { int x,y,id; }a[maxn]; bool cmp1(node a,node b) { if(a.x!=b.x)return a.x<b.x; return a.y<b.y; } bool cmp2(node a,node b) { if(a.y!=b.y)return a.y<b.y; return a.x<b.x; } bool cmp3(node a,node b) { if(a.x+a.y!=b.x+b.y)return a.x+a.y<b.x+b.y; return a.x<b.x; } bool cmp4(node a,node b) { if(a.x-a.y!=b.x-b.y)return a.x-a.y<b.x-b.y; return a.x<b.x; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].id=i; sort(a+1,a+m+1,cmp1); for(int i=1;i<=m;i++) { if(i>1&&a[i-1].x==a[i].x)ans[a[i].id]++; if(i<m&&a[i].x==a[i+1].x)ans[a[i].id]++; } sort(a+1,a+m+1,cmp2); for(int i=1;i<=m;i++) { if(i>1&&a[i-1].y==a[i].y)ans[a[i].id]++; if(i<m&&a[i].y==a[i+1].y)ans[a[i].id]++; } sort(a+1,a+m+1,cmp3); for(int i=1;i<=m;i++) { if(i>1&&a[i-1].x+a[i-1].y==a[i].x+a[i].y)ans[a[i].id]++; if(i<m&&a[i].x+a[i].y==a[i+1].x+a[i+1].y)ans[a[i].id]++; } sort(a+1,a+m+1,cmp4); for(int i=1;i<=m;i++) { if(i>1&&a[i-1].x-a[i-1].y==a[i].x-a[i].y)ans[a[i].id]++; if(i<m&&a[i].x-a[i].y==a[i+1].x-a[i+1].y)ans[a[i].id]++; } for(int i=1;i<=m;i++)num[ans[i]]++; for(int i=0;i<=8;i++)printf("%d%c",num[i],i==8?'\n':' '); return 0; }