题意:一个n*n的棋盘中放置m个点,每个点会占用所在的两条斜对角线,问最后有多少个格子没有被占用
题解:按从左上往右下(id = n+x-y)对角线pos, 从右上往左下(id = x+y-1) 对角线neg分成两部分,dp[i]表示第i条neg对角线没有被占用的格子数,然后根据pos找规律递推neg没有被占用的格子,最后判断neg上有没有被占用进行累加
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <map>
#include <sstream>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000009
#define eps 1e-6
const int maxn = 1000000;
bool pos[maxn];
bool neg[maxn];
int dp[maxn];//第i条neg对角线上有多少个点没有被覆盖
using namespace std;
int main(){
int T, kases = 1;
scanf("%d",&T);
while(T--){
memset(pos, false, sizeof(pos));
memset(neg, false, sizeof(neg));
memset(dp, 0, sizeof(dp));
int n,m;
scanf("%d%d",&n,&m);
int x,y;
for(int i=0; i<m; i++){
scanf("%d%d",&x,&y);
pos[n+x-y] = true;
neg[x+y-1] = true;
}
if(!pos[n]) dp[2*n-1] = dp[1] = 1;
for(int i=2; i<=n; i++){
dp[i] = dp[i-2];
int id = n-i+1;
if(!pos[id]) dp[i]++;
if(!pos[2*n-id]) dp[i]++;
}
for(int i=2*n-2; i>=n+1; i--){
dp[i] = dp[i+2];
int id = i-n+1;
if(!pos[id]) dp[i]++;
if(!pos[2*n-id]) dp[i]++;
}
int ans = 0;
for(int i=1; i<=2*n-1; i++){
if(!neg[i]) ans += dp[i];
}
printf("Case #%d: %d\n",kases++,ans);
}
}