Codeforces-1474-D (思维-消数问题)

题目

传送门https://codeforces.com/contest/1474/problem/D

During cleaning the coast, Alice found n piles of stones. The i-th pile has ai stones.
Piles i and i+1 are neighbouring for all 1≤i≤n−1. If pile i becomes empty, piles i−1 and i+1 doesn’t become neighbouring.
Alice is too lazy to remove these stones, so she asked you to take this duty. She allowed you to do only the following operation:

  • Select two neighboring piles and, if both of them are not empty, remove one stone from each of them.

Alice understands that sometimes it’s impossible to remove all stones with the given operation, so she allowed you to use the following superability:

  • Before the start of cleaning, you can select two neighboring piles and swap them.

Determine, if it is possible to remove all stones using the superability not more than once.

思路

这题比赛时没做出来……

  • 看评论有个这样的解法:
    在这里插入图片描述
  • 还有题解的做法:
    在这里插入图片描述
  • 注意

case 0 那里不能单纯判断 s[n]==0,我一开始这样写的,一直 WA,调了好久才发现……因为还需要 Smark 显示整个过程未出现负数,此时 s[n] 才是有效的值。

代码

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define N 200//005
int T,n,a[N];
int s[N],p[N],Smark,Pmark;

int main()
{
    
    
	
	scanf("%d",&T);
	while (T--) {
    
    
		scanf("%d",&n);
		for (int i=1; i<=n; i++)
			scanf("%d",&a[i]);
		
		//从左往右依次消,消到出现负数或者消完为止,用 Smark 记录一下情况
		s[0]=0;
		Smark=n+1;
		for (int i=1; i<=n; i++) {
    
    
			s[i]=a[i]-s[i-1];
			if (s[i]<0) {
    
    
				Smark=i;
				break;
			}
		}
		
		//从右往左依次消,消到出现负数或者消完为止,用 Pmark 记录一下情况
		p[n+1]=0;
		Pmark=0;
		for (int i=n; i>=1; i--) {
    
    
			p[i]=a[i]-p[i+1];
			if (p[i]<0) {
    
    
				Pmark=i;
				break;
			}
		}
		
		//case0 消完了,不需要调换
		if (Smark==n+1 && s[n]==0) {
    
    
			puts("YES");
			continue;
		}
		
		//case1 从左往右和从右往左第一次出错的点相聚远,肯定无法只调换相邻两个而成功
		//好像这一类不需要单独拎出来讨论,因为这种情况下面自动跳过for循环
		if (Smark<Pmark-1) {
    
    
			puts("NO");
			continue;
		}
		
		//case2 判断能否通过调换相邻两个而成功
		int fail=1;
		for (int i=Smark; i+1>=Pmark; i--) if (i>0 && i<n) {
    
    
			swap(a[i],a[i+1]);
			
			//a[i]=   s[i-1] + (a[i]-s[i-1])
			//a[i+1]= p[i+2] + (a[i+1]-p[i+2])
			
			if (a[i]-s[i-1]>=0 && a[i+1]-p[i+2]>=0 && a[i]-s[i-1]==a[i+1]-p[i+2] && s[i-1]>=0 && p[i+2]>=0) {
    
    
				fail=0;
				break;
			}
			
			swap(a[i],a[i+1]);
		}
		puts(fail ? "NO" : "YES");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jackypigpig/article/details/112858482
今日推荐