Codeforces Round #802 (Div. 2)
作者:互联网
A. Optimal Path
思路:
最小就是走第一行和最后一列
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 200010; int a[N]; void solve() { int n, m; cin >> n >> m; LL res = 0; for (int i = 1; i <= m; i ++ ) res += i; for (int i = 2; i <= n; i ++ ) res += (i - 1) * m + m; cout << res << endl; } int main() { int T; cin >> T; while(T -- ) { solve(); } return 0; }
B. Palindromic Numbers
思路:
因为不能有前导零,所以开头是9用高精度减法让n+1个1减去s,开头不是9就让最终加起来结果等于n个9
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 200010; int a[N]; vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i++) { t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); if (t < 0) t = 1; else t = 0; } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } void solve() { int n; string s; cin >> n >> s; if(s[0] == '9') { string a = ""; for (int i = 0; i < n + 1; i ++ ) a += '1'; vector<int> A, B; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = s.size() - 1; i >= 0; i--) B.push_back(s[i] - '0'); vector<int> C; C = sub(A, B); for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; cout << endl; } else { for (int i = 0; i < s.size(); i ++ ) cout << 9 - (s[i] - '0'); cout << endl; } } int main() { int T; cin >> T; while(T -- ) { solve(); } return 0; }
C. Helping the Nature
思路:
很明显是差分,最终要让原数组等于0等价于让差分数组等于0。分析给出的三个操作:对应到差分数组就是
所以对于1操作,其他数加一会让d1减一,而最后我们可以再让d1执行3操作抵消这一影响。所以我们可以最后再考虑d1,对于di大于0的,我们直接执行2操作让di等于0。对于di小于0的,我们就要执行1操作,让di变成0,而1操作会影响d1,因为di是负的,所以我们加了多少个1让di变成0就相应的要让d1减去多少个1。最后对于d1执行3操作或2操作,取决于d1是正的还是负的。
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 200010; LL a[N], d[N]; void solve() { int n; cin >> n; for (int i = 1; i <= n; i ++ ) cin >> a[i], d[i] = a[i] - a[i - 1]; LL res = 0; for (int i = 2; i <= n; i ++ ) if(d[i] > 0) res += d[i]; else if(d[i] < 0) { res += -d[i]; d[1] += d[i]; } res += abs(d[1]); cout << res << endl; } int main() { int T; cin >> T; while(T -- ) { solve(); } return 0; }
D. River Locks
思路:
对于-1的情况就是如果t太小就不可能完成,那这个下限这么考虑:前一个水龙头放满水时间是v1/1,前两个是(v1+v2)/2,以此类推,前i个就是(v1+……+vi)/ i,注意要向上取整。在其中取最大值,说明这就是最少要用多少时间。然后因为我们要求水龙头数量的最小值,所以我们可以用二分来求,因为要放满n个池子,假设我们开了x个水龙头,那所需时间就是(v1+……+vn)/ x,这里因为时间是t,我们可以转换成乘法,二分的check条件就可以写成x*t>=s[n]
#include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 200010; LL a[N], s[N]; void solve() { int n; cin >> n; LL mxv = 0; for (int i = 1; i <= n; i ++ ) { cin >> a[i]; s[i] = s[i - 1] + a[i]; mxv = max(mxv, (s[i] + i - 1) / i);//上取整 } int q; cin >> q; while(q -- ) { int t; cin >> t; if(t < mxv) cout << -1 << endl; else { int l = 1, r = n; while(l < r) { int mid = l + r >> 1; if (1ll * mid * t >= s[n]) r = mid; else l = mid + 1; } cout << r << endl; } } } int main() { int T = 1; //cin >> T; while(T -- ) { solve(); } return 0; }
标签:typedef,int,LL,Codeforces,long,--,solve,802,Div 来源: https://www.cnblogs.com/yctql/p/16536941.html