zoukankan      html  css  js  c++  java
  • 【Codeforces Round #693 (Div. 3) F】New Year's Puzzle

    题目链接

    链接

    翻译

    给你一个 (2*n) 的方格,让你用 (1*2) 的骨牌,横着或者竖着放,铺满整个方格。

    其中有一些被黑色方块阻挡,不能放骨牌。问你可不可行。

    题解

    首先考虑 整个方格 第一列,如果两行都是空的。

    那么考虑第二列的几种情况:

    • 第二列也是空的,那么第一列放竖的没问题。
    • 第二列有一个方格被堵住了,那么第一列只能竖着放了,不然铺不满(注意这是第一列,它之前没有列了)
    • 第二列有两个方格都被堵住了,那么第一列也同样是竖着放。

    综上所述,第一列如果两行都是空的,那么就竖着放一个就行。

    这样就可以不断地 (Reduce) 问题。然后如果新的第一列还是空的,就不断缩减。

    当然,如果第一列两行都被堵住了,那么同样的也可以缩减问题,因为这一列不用放骨牌...

    这样,我们的问题的第一列就总是只有一个方格被堵住的情况了。

    这个时候我们只能放一个横的骨牌,会突出来一部分。而且,如果它的右边仍然是两行都是空着的情况,那么又得继续横着放一个。

    直到遇到某个位置也恰好只有一行被堵住,则需要判断一下能不能刚好填满两行。所以中间的大概 (n-m) 个空格可以直接跳过。

    这里能否填满两行的情况需要根据前后两个 只有一行被堵住 的列的坐标差的奇偶性来判断,为奇数,则被堵住的行号应该相同。否则,应该不同。

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int N = 2e5;
    const LL MOD = 1e9 + 7;
    const int K = 5000;
    
    int n, m;
    map<int, int> dic;
    
    int main() {
    	#ifdef LOCAL_DEFINE
    		freopen("in.txt", "r", stdin);
    	#endif
    	ios::sync_with_stdio(0), cin.tie(0);
    	int T;
    	cin >> T;
    	while (T--) {
    		dic.clear();
    		cin >> n >> m;
    		for (int i = 1; i <= m; i++) {
    			int r, c;
    			cin >> r >> c;
    			dic[c] |= (1 << (r - 1));
    		}
    		//reduce
    		map<int,int>::iterator it = dic.begin();
    		while (it != dic.end()) {
    			pair<int, int> temp = *it;
    			if (temp.second == 0 || temp.second == 3) {
    				m--;
    				it++;
    				continue;
    			}
    			else {
    				break;
    			}
    		}
    		if (it == dic.end()) {
    			cout << "YES" << endl;
    			continue;
    		}
    		//it.second == 2 || it.second == 1
    		pair<int,int> pre = (*it);
    		it++;
    		bool ok = true;
    		while (it != dic.end()) {
    			if (pre.second == 0 || pre.second == 3) {
    				pre = (*it);
    				it++;
    				continue;
    			}
    			int temp = (*it).second;
    			int delta = (*it).first - pre.first;
    			if (temp == 0) {
    				if (delta%2 == 0) {
    					pre.second = 3 - pre.second;
    				}
    				pre.first = (*it).first;
    			}
    			else if (temp == 1 || temp == 2){
    				if (delta % 2 == 0) {
    					if (temp != pre.second) {
    
    					}
    					else {
    						ok = false;
    						break;
    					}
    				}
    				else {
    					if (temp == pre.second) {
    
    					}
    					else {
    						ok = false;
    						break;
    					}
    				}
    				pre = *it;
    				pre.second = 3;
    				it++;
    			}
    			else {
    				//temp==3
    				if (pre.second != 0 && pre.second != 3) {
    					ok = false;
    					break;
    				}
    				it++;
    			}
    		}
    		if (!ok || pre.second == 1 || pre.second == 2) {
    			cout << "NO" << endl;
    		}
    		else {
    			cout << "YES" << endl;
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    php_sphinx安装使用
    获取数据库中所有表名
    总结thinkphp快捷查询getBy、getField、getFieldBy用法及场景
    打印机复印身份证方法
    svn 删除、移动和改名
    MySQL中REGEXP正则表达式使用大全
    高铁在高速运行时的电力是如何提供的?
    2016亚洲大学排名
    Mac下安装HBase及详解
    HBase Mac OSX 安装笔记
  • 原文地址:https://www.cnblogs.com/AWCXV/p/14274476.html
Copyright © 2011-2022 走看看