【思维构造】Queries for the Array—CF1861C

Queries for the Array—CF1861C
本题方法参考:
Educational Codeforces Round 154 (Rated for Div. 2) 作者:不如讨饭
比赛的时候没有写到这个题,赛后补题的时候发现这个很不好想。
最后才找到一个比较好理解的方法。
又花了好长时间才把这个方法给全部理解了。
万年好题!!!

C o d e Code Code

#include 
#define int long long
#define sz(a) ((int)a.size())
using namespace std;
const int N = 2e5 + 10;

void solve() {
	string s; cin >> s;
	vector <int> a(sz(s) + 1, 0); // a[i]的值为1、0、-1:长度为i的数组分别是升序、单调性没有要求、降序
	int len = 0; // 数组的长度
	a[0] = 1; 
	// 因为“Every array with less than 2 elements is considered sorted.”
	// 所以要令a[0] = 1;
	for (int i = 0; i <= sz(s) - 1; i ++) {
		if (s[i] == '+') { // 数组末尾加一个元素
			// 如果数组原来是降序,那么新数组也是降序
			// 否则新数组可以是升序或降序(a[len + 1] = 0)
			if (a[len] == -1) { 
				a[len + 1] = -1;
			}
			len ++;
		} else if (s[i] == '-') { // 数组末尾减去一个元素
			/*
			  如果数组原来是升序且len>=2,那么新数组也应该是升序
			  证明:
			  因为数组原来是升序,那么s字符串在i位置左边的一个最近的'1'的规定下(即要求数组升序)必定使a[len - 1] = 1
			  所以这里把最后一个元素删去后需要令a[len - 1] = 1;
			 */
			if (a[len] == 1 && len >= 2) {
				a[len - 1] = 1;
			}
			a[len] = 0;
			len --;
		} else if (s[i] == '1') {
			if (a[len] == -1) {
				cout << "NO\n";
				return;
			}
			a[len] = 1;
		} else {
			if (a[len] == 1 || len == 1) {
				cout << "NO\n";
				return;
			}
			a[len] = -1;
		}
	}
	cout << "YES\n";
}

signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	cin >> t; cin.get();
	while (t --) solve();
	return 0;
}

你可能感兴趣的:(思维构造,算法,数据结构)