携程笔试 9/7
写一下t4的题解,前面几题都比较简单就不写了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <stack>
using namespace std;
#define pii pair<int,int>
#define ll long long
#define mst(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(ll i=(a);i<(b);i++)
int main() {
string s; cin >> s;
int n = s.size();
ll res = 0;
vector<int> dp(n+1); // cnt of 0
rep(i, 0, n) {
dp[i+1] = s[i] == '0'? dp[i]+1:dp[i];
}
rep(i, 0, n+1) {
dp[i] = 2*dp[i]-i;
}
stack<int> stk;
ll sum = 0;
rep(i, 0, n+1) {
while(stk.size() > 0 && dp[stk.top()] >= dp[i]) {
stk.pop();
}
res += stk.size();
stk.push(i);
}
cout << res << endl;
return 0;
}
要求0的数量严格大于1,用dp记录一下0的数量,下标从1开始,减的时候不用考虑边界情况。
对于[i,j]如果满足条件,必要条件是2*(dp[j]-dp[i-1]) > j-i+1,转换一下就是2*dp[j]-j>2*dp[i-1]-i+1,所以可以把dp的含义设置为2倍的0的数量减掉index。
随后发现题目要求就是对于每一个j,找出满足j>i&&dp[j] < dp[i]的i的数量,于是显然用单调栈可以解决。

华为HUAWEI公司氛围 747人发布
查看4道真题和解析