zoukankan      html  css  js  c++  java
  • 【Codeforces Round #696 (Div. 2) D】Cleaning

    题目链接

    链接

    翻译

    你可以选择相邻的两个都不为空的石头堆,从两个石头堆(每个石头堆中有多个石头)中都拿去一个石头。

    你可以进行无数次这样的操作,问你最终能否将所有的石头都拿走。

    石头是在一条直线上排列的,从左到右标号为 (1)(n)

    题解

    会发现第一个位置上的石头,只能通过拿堆 (1) 和堆 (2) 全部拿走。

    然后堆 (1) 全拿完之后,堆 (2) 变成新的堆 (1) 了,所以也只能拿头两堆的石头。

    以此类推,我们就可以这样每次贪心地拿头两堆完成一次 (check),看是否能够在不使用超能力的情况下拿走全部石头了。

    如果不能够做到的话,就需要使用超能力了。

    这里先提醒一点,我们同样可以从最后一堆开始拿起,因为最后一堆也只能通过每次拿倒数的两堆实现全都拿走。

    因此,我们可以设 (pre_i)(suf_i) 分别表示 (1..i-1) , (i+1..n) 这些堆的石头全部被拿走了,然后第 (i) 堆石头剩余的石头数目。

    会发现我们交换相邻的两堆石头 (i)(i+1), 问题就转化为 (pre_{i-1})(a[i+1]) 以及 (a[i])(suf_{i+2}) 这四个位置的石头堆能否全都

    拿走了,因为 (1..i-2)(i+3..n) 这些位置上的石头能否拿走都不会受这次 (swap) 的影响。

    (mathcal{O}(N)) 枚举交换位置即可。

    代码

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    
    const int N = 2e5;
    
    int T, n;
    int a[N + 10],pre[N+10],suf[N+10];
    
    bool ok(vector<int> v) {
    	int len = v.size();
    	for (int i = 0; i <= len - 2; i++) {
    		if (v[i] < 0) {
    			return false;
    		}
    		v[i + 1] -= v[i];
    		v[i] = 0;
    	}
    	for (int x : v) {
    		if (x != 0) {
    			return false;
    		}
    	}
    	return true;
    }
    
    int main() {
    	#ifdef LOCAL_DEFINE
    		freopen("in.txt", "r", stdin);
    	#endif // LOCAL_DEFINE
    	ios::sync_with_stdio(0), cin.tie(0);
    	cin >> T;
    	
    	while (T--) {
    		cin >> n;
    		for (int i = 1; i <= n; i++) {
    			cin >> a[i];
    		}
    		pre[1] = a[1];
    		for (int i = 2; i <= n; i++) {
    			if (pre[i - 1] < 0) {
    				pre[i] = -1;
    				continue;
    			}
    			pre[i] = a[i] - pre[i - 1];
    		}
    		suf[n] = a[n];
    		for (int i = n - 1; i >= 1; i--) {
    			if (suf[i + 1] < 0) {
    				suf[i] = -1;
    				continue;
    			}
    			suf[i] = a[i] - suf[i + 1];
    		}
    		if (pre[n] == 0) {
    			cout << "YES" << endl;
    			continue;
    		}
    		bool finalOK = false;
    		for (int i = 1; i <= n - 1; i++) {
    			//swap(a[i],a[i+1])
    			vector<int> v(0);
    			if (i > 1) {
    				v.push_back(pre[i - 1]);
    				if (pre[i - 1] < 0) {
    					continue;
    				}
    			}
    			v.push_back(a[i+1]);v.push_back(a[i]);
    			if (i <= n - 2) {
    				if (suf[i + 2] < 0) {
    					continue;
    				}
    				v.push_back(suf[i+2]);
    			}
    			if (ok(v)) {
    				finalOK = true;
    				break;
    			}
    		}
    		if (finalOK) {
    			cout << "YES" << endl;
    		}
    		else {
    			cout << "NO" << endl;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python学习(十六)内置函数,递归
    Python学习(十五)json串使用,不固定参数,关键词参数
    Python学习(十四)常量,局部变量,全局变量
    python学习(十三)函数
    python学习(十二)模块
    Python学习(十一)文件指针,文件操作练习,修改文件
    mongodb聚合
    mongodb
    软件测试需要学习哪些课程
    Jmeter的使用和监控分析
  • 原文地址:https://www.cnblogs.com/AWCXV/p/14471498.html
Copyright © 2011-2022 走看看