Codeforces Round #693 (Div. 3) - F. New Year‘s Puzzle(分类讨论)

58 篇文章 0 订阅
13 篇文章 1 订阅
本文详细介绍了Codeforces Round #693 (Div. 3)中的一道题目F.NewYear's Puzzle。题目要求在给定的2*n矩形中,排除一些禁用区域,使用2*1和1*2的砖块将其完全覆盖。文章通过分类讨论的方法,分析了不同情况下的解决方案,并提供了AC代码。主要涉及算法和编程思维。
摘要由CSDN通过智能技术生成

Codeforces Round #693 (Div. 3) 全文见:https://blog.csdn.net/qq_43461168/article/details/112596814

F. New Year’s Puzzle

题意:给定一个2*n的矩形。不过有一些块被ban掉了。然后用 2*1 和 1*2 的砖头把他铺满。问能否铺满。在这里插入图片描述

思路:其实就一个分类讨论的题。先对黑块排个序。然后遍历。分很多种情况。先假设 up = 1表示 底下是黑块,而上面放了一个躺着的块。 down = 1表示下面放了一个躺着的块。来表示两种状态。用 last 表示 上一个黑块的位置 如图:

在这里插入图片描述

然后分类讨论了。

1. 上下都是黑块。那前面必须 down 和 up 都为0才行。也就是不会能铺满2*k的格子而不会凸出来一个。
2. 上面是黑块。有五种情况,第一种就是down 和 up 都为0,那么必须放一个躺着的,剩下的情况:中间的白块数量只是代表距离的奇偶性。

在这里插入图片描述

3. 下面是黑块。有五种情况,第一种同上就是down 和 up 都为0,那么必须放一个躺着的,剩下的情况。 和上面一样分析。 倒过来就行了。

AC代码:

#include <iostream>
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 1e6+7;
int n,m,k,t = 1,cas = 1;
//int a[N],b[N];
struct node{
    int x,y;
}a[N];

bool cmp(node a1,node a2){
    return a1.y < a2.y;
}

signed main(){
    cin>>t;
    while(t--){
        cin>>n>>m;
        int maxx = 0;
        for(int i = 0 ; i < m ; i ++){
            cin>>a[i].x>>a[i].y;
            maxx = max(a[i].y,maxx);
        }
        a[m].x = 1,a[m++].y = maxx+1;
        a[m].x = 2,a[m++].y = maxx+1;
        sort(a,a+m,cmp);
        int up = 0;
        int down = 0;
        int flag = 1;
        int last = 0;
        for(int i = 0; i < m ; i ++){
            //cout<<a[i].x<<" "<<a[i].y<<" "<<up<<" "<<down<<endl;
            if((i+1) < m && a[i+1].y == a[i].y){
                if(up || down){
                    flag = 0;
                    break;
                }
                i ++;
            }else if(a[i].x == 1){
                int dis = a[i].y - last - 1;
                if(dis%2){  // 距离为奇数
                    if(down == 0 && up == 0){
                        down = 1;
                    }else if(down){
                        flag = 0;
                        break;
                    }else{
                        up = 0;
                        down = 0;
                    }
                }else{      // 距离为偶数
                    if(down == 0 && up == 0){
                        down = 1;
                    }else if(down){
                        up = 0;
                        down = 0;
                    }else{
                        flag = 0;
                        break;
                    }
                }
            }else{
                int dis = a[i].y - last - 1;
                if(dis%2){  // 距离为奇数
                    if(up == 0 && down == 0){
                        up = 1;
                    }else if(up){
                        flag = 0;
                        break;
                    }else{
                        up = 0;
                        down = 0;
                    }
                }else{      // 距离为偶数
                    if(up == 0 && down == 0){
                        up = 1;
                    }else if(up){
                        down = 0;
                        up = 0;
                    }else{
                        flag = 0;
                        break;
                    }
                }
            }
            last = a[i].y;
        }
        puts(flag ? "YES" : "NO");
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值