zoukankan      html  css  js  c++  java
  • Codeforces Round #696 (Div. 2) D. Cleaning (思维,前缀和)

    • 题意:有一堆石子,你每次可以选择相邻(就算两堆石子中间有很多空堆也不算)的两堆石子,使得两堆石子的个数同时(-1),你在刚开始的时候有一次交换相邻石子的机会,问你最后能否拿走所有石子.
    • 题解:对于第一堆石子和最后一堆石子,它们只能靠第二堆石子和倒数第二堆石子减去才合法,所以我们由第一堆石子不断向右推和最后一堆石子不断向左推,这个过程可以用前缀和(pre)与后缀和(suf)表示.如果我们当前选择堆(<i-1,i>)的话,那么前缀和(pre[i-2])和后缀和(suf[i+1])是不会受到任何影响的,如果问题出在我们当前选择的这个堆上的话,我们就必须保证(pre[i-2])(suf[i+1])都是合法的,同时,我们将(pre[i-2])(a[i-1])合并后和(suf[i+1])(a[i])合并后的值应该是合法且相等的.于是乎,我们可以枚举所有堆,然后判断不反转和反转是否合法.这里注意,如果(pre[i])不合法,我们将(pre[i]=-1),那么(i)后面的(pre)也都是不合法的,都标记为(-1),(suf)同理.
    • 代码:
    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    int _;
    int a[N];
    int pre[N],suf[N];
    
    bool check(int i){
    	if(pre[i-2]!=-1 && suf[i+1]!=-1 && a[i-1]>=pre[i-2] && a[i]>=suf[i+1] && a[i-1]-pre[i-2]==a[i]-suf[i+1])
    		return true;
    	return false;
    }
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    
    	cin>>_;
    	while(_--){
    		int n;
    		cin>>n;
    		rep(i,1,n) cin>>a[i];
    
    		pre[0]=0,suf[n+1]=0;
    
    		rep(i,1,n){
    			if(pre[i-1]==-1 || a[i]<pre[i-1]){
    				pre[i]=-1;
    			}else{
    				pre[i]=a[i]-pre[i-1];
    			}
    		}
    
    		per(i,n,1){
    			if(suf[i+1]==-1 || a[i]<suf[i+1]){
    				suf[i]=-1;
    			}else{
    				suf[i]=a[i]-suf[i+1];
    			}
    		}
    
    		bool flag=false;
    
    		rep(i,2,n){
    			if(check(i)) {flag=true;break;}
    			swap(a[i],a[i-1]);
    			if(check(i)) {flag=true;break;}
    			swap(a[i],a[i-1]);
    			if(pre[i-1]==-1) break; //小小的优化
    		}
    
    		if(flag) cout<<"YES
    ";
    		else cout<<"NO
    ";
    	}
    
        return 0;
    }
    
  • 相关阅读:
    递归
    linq语法
    客户端(winform)更新
    c# 实时监控数据库 SqlDependency
    C# MVC NPOI导出
    mui手机图片压缩上传+C#
    vs连接Oracle 客户端库时引发 BadImageFormatException
    一对多的子表数据利用游标循环更新主表的数据
    数据库的恢复数据语句
    mysql三-2:数据类型
  • 原文地址:https://www.cnblogs.com/lr599909928/p/14342781.html
Copyright © 2011-2022 走看看