递推/思维 Codeforces Round #693 (Div. 3) F题

递推/思维 Codeforces Round #693 (Div. 3) F题

题意:给一个2 * n 的方格,要求用 1 * 2 的骨牌,横着或者竖着放,铺满整个方格。
其中有一些被黑色方块阻挡,不能放骨牌 , 问是否可行?

解析:
首先,如果黑色堵块为奇数个,直接输出NO
考虑 整个方格 第一列

如果两行都是空的

那么考虑第二列的几种情况:
        - 第二列也是空的,那么第一列可以竖着放。
        - 第二列有一个方格被堵住了,那么第一列只能竖着放
        - 第二列有两个方格都被堵住了,那么第一列也只能竖着放
所以第一列如果两行都是空的,竖着放就好。接下来继续往后考虑即可。

如果第一列两行都被堵住,同样继续考虑后面的即可。

如果第一列只有一行被堵住,则只能在没堵住的那一行放一个横着的骨牌,并且如果下一列如果仍然两行都是空的话,则又继续在没堵住的一行放一个横着的骨牌,直到某个位置也只有一行被堵住,没堵住的那一行正好可以放得下横着的骨牌,那就正好全部凑满了,继续考虑下一对即可。

这里可以根据前后两个只有一行被堵住的列的坐标差的奇偶性来判断,横坐标相减为奇数,则被堵住的行号应该相同。否则,应该不同。并且要保证第奇数个黑格子不与其前一个在同一列

int t,n,m;
struct node{
    int x,y;
    bool operator<(const node &t)const{
        if(y == t.y) return x < t.x;
        return y < t.y;
    }
}a[N];
void solve(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    if(m & 1){
        puts("NO");
        return;
    }
    sort(a+1,a+1+m);
    for(int i=2;i<=m;i++){
        if(i & 1){
            if(a[i].y == a[i-1].y){
                puts("NO");
                return;
            }
        }else{
            int tmp1 = (a[i].y - a[i-1].y) % 2;
            int tmp2 = abs(a[i].x - a[i-1].x);
            if(tmp1 == tmp2){
                puts("NO");
                return;
            }
        }
    }
    puts("YES");
}
int main(){
    scanf("%d",&t);
    while(t--){
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值