UVA 11261(递推+找规律)

题意:一个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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值