首页 > 代码库 > 洛谷2105 k皇后

洛谷2105 k皇后

P2105 K皇后

题目描述

小Z最近捡到了一个棋盘,他想在棋盘上摆放K个皇后。他想知道在他摆完这K个皇后之后,棋盘上还有多少了格子是不会被攻击到的。

(Ps:一个皇后会攻击到这个皇后所在的那一行,那一列,以及两条对角线)

输入输出格式

输入格式:

 

第一行三个正整数 n,m,K,表示棋盘的行列,以及小Z摆放了K个皇后。

接下来K行,每行两个正整数x,y,表示这个皇后被摆在了第x行,第y列,数据保证没有任何两个皇后会被摆在同一个格子里。

 

输出格式:

 

一行一个整数,表示棋盘上还有多少了格子是不会被攻击到的。

 

输入输出样例

输入样例#1:
12 13 6
10 4
12 10
1 1
2 3
3 2
2 6
输出样例#1:
25

说明

【数据规模和约定】

对于 30%的数据,1 ≤ n,m ≤ 5000,1 ≤ k ≤ 500。

对于另外 10%的数据,k =1。

对于 100%的数据,1 ≤ n,m ≤ 20000,1 ≤ k ≤ 500。

【时空限制】

1s/16M

枚举一行
{
  枚举一个皇后
  {
    皇后控制的一行就是这一行continue
    皇后控制的一列存在于这一行的位置没有讨论过ans++,标记
    皇后控制的一条对角线存在于这一行的位置没有讨论过ans++,标记
    皇后控制的另一条对角线存在于这一行的位置没有讨论过ans++,标记
  }
}

#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int x[501],y[501],h[20001];
int main()
{
    int n,m,k,i,j,ans,t;
    scanf("%d%d%d",&n,&m,&k);
    memset(h,0,sizeof(h));
    for (i=1;i<=k;i++) scanf("%d%d",&x[i],&y[i]);
    ans=0;
    for (i=1;i<=n;i++)
    {
        t=m;
        for (j=1;j<=k;j++)
            if (x[j]==i)
            {
                t=0;
                break;
            } 
            else
            {
                if (h[y[j]]!=i)
                {
                    h[y[j]]=i;
                    t--;
                }
                if ((i+y[j]-x[j])>0 && (i+y[j]-x[j])<=m && h[i+y[j]-x[j]]!=i)
                {
                    h[i+y[j]-x[j]]=i;
                    t--;
                }
                if ((y[j]+x[j]-i)>0 && (y[j]+x[j]-i)<=m && h[y[j]+x[j]-i]!=i)
                {
                    h[y[j]+x[j]-i]=i;
                    t--;
                }
            }
        ans+=t;
    }
    printf("%d\n",ans);
    return 0;
}

 

洛谷2105 k皇后