Problem B
Bishops
Input: Standard Input
Output: Standard Output
Little Sultan has a new chess set. But he finds it more amusing to make some new variants of his own than the original game of chess. Here he challenges you with one of his new variants. On a n×n chessboard m bishops are placed. You have to calculate how many square cells of the chessboard are not attacked by any of those bishops.
Input
On the first line you will be given L which denotes the number of input sets you have to process. For each of the input sets, you will have the following:
n, m on a line.
Each of the following m lines will have two integers: r_i and c_i denoting the row and column position of the bishops (1-based).
Output
For each input set, output the set number as the sample output suggests and the number of cells which are not attacked by any of the bishops.
Constraints
1. 1 <= n <= 40000
2. 0 <= m <= 10000
3. The positions for the bishops will be distinct.
4. 1 <= r_i, c_i <= n
Sample Input | Sample Output |
2 1 1 1 1 2 1 2 1
| Case #1: 0 Case #2: 2
|
Problemsetter: Istiaque Ahmed
Special Thanks To: Manzurur Rahman Khan
题目大意:
国际象棋 象
T组测试数据,对于每组测试数据 ,给你一个 n ,m 分别表示n*n的棋盘,以及 m个象的位置,(国际象棋中象攻击的范围是两道斜线),
接下来 m 行 表示 象的位置,让你求棋盘中有多少位置不受攻击。
解题思路:
这个题n*n暴力的算法肯定不行。但是可以记录一下每个象覆盖的斜线,然后枚举 2*n-1 条左上右下的这种斜线,斜线上有象的肯定会被攻击到,
没有象的这条斜线上的位置有些可能会被一些左下右上的斜线穿过而覆盖,而这时如果枚举穿过的斜线肯定超时,但是可以预处理好,利用递推
的方式就不会超时。
算法总效率 O(n)左右。
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=80010;
bool coverl[maxn],coverr[maxn];
int dp[maxn];
int n,m;
void input(){
int x,y;
for(int i=0;i<=2*n;i++){
coverl[i]=false;
coverr[i]=false;
}
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
coverl[n+x-y]=true;
coverr[x+y-1]=true;
}
}
void getdp(){
dp[2*n]=dp[0]=0;
if(coverl[n]) dp[2*n-1]=dp[1]=0;
else dp[2*n-1]=dp[1]=1;
for(int i=2;i<=n;i++){
dp[i]=dp[i-2];
int num=n-i+1;
if(!coverl[num]) dp[i]++;
if(!coverl[2*n-num]) dp[i]++;
}
for(int i=2*n-2;i>=n+1;i--){
dp[i]=dp[i+2];
int num=i-n+1;
if(!coverl[num]) dp[i]++;
if(!coverl[2*n-num]) dp[i]++;
}
}
void solve(int casen){
int ans=0;
getdp();
for(int i=1;i<2*n;i++){
if(coverr[i]) continue;
ans+=dp[i];
}
printf("Case #%d: %d\n",casen,ans);
}
int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
input();
solve(i);
}
return 0;
}