因为现在太渣了只能做div2;争取每次div2都做出4题,然后提高自己能力之后,再来个5题全过,所以下面只有四题的题解;
题A
题意:给你两个数,但是用的是数组来表示,每个数有n个数,然后有一个基数base,也就是base进制的意思,然后问你这两个数那个比较大。
题解:水题,直接开龙龙模拟
1 /*zhen hao*/ 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 typedef long long ll; 6 int val[50]; 7 8 int main() { 9 //freopen("case.in", "r", stdin); 10 int n, base; 11 cin >> n >> base; 12 for (int i = 0; i < n; i++) cin >> val[i]; 13 ll x = 1, num1 = 0, num2 = 0; 14 for (int i = n - 1; i >= 0; i--) { 15 num1 = num1 + val[i] * x; 16 x *= base; 17 } 18 cin >> n >> base; 19 for (int i = 0; i < n; i++) cin >> val[i]; 20 x = 1; 21 for (int i = n - 1; i >= 0; i--) { 22 num2 = num2 + val[i] * x; 23 x *= base; 24 } 25 if (num1 > num2) puts(">"); 26 else if (num1 < num2) puts("<"); 27 else puts("="); 28 }
题B
题意:给你一串数字,保证相邻两个一定满足|ai – ai+1| <= 1,然后定义一个区间:这个区间的最大值和最小值的差不超过一,也就是max – min <= 1,然后问你最长的区间是多少。
题解:dp[v][0]表示[v-1,v],dp[v][1]表示[v,v+1];然后就是来一个数,更新相应的状态,然后要注意的是因为要求的是区间,也就是连续,所以记得相应的状态变成0,也就是dp[v-1][0],dp[v+1][1],还有dp[v+2]和dp[v-2]的状态都要还原成0,就是没注意这个wa了几次。
1 /*zhen hao*/ 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int maxn = 100000 + 100; 6 int val[maxn], dp[maxn][3]; 7 8 int main() { 9 //freopen("case.in", "r", stdin); 10 int n; 11 scanf("%d", &n); 12 for (int i = 1; i <= n; i++) 13 scanf("%d", val + i); 14 memset(dp, 0, sizeof(dp)); 15 int ans = 0; 16 for (int i = 1; i <= n; i++) { 17 int v = val[i]; 18 dp[v][0]++; dp[v][1]++; 19 dp[v - 1][1]++; dp[v + 1][0]++; 20 dp[v - 1][0] = dp[v + 1][1] = 0; 21 if (i > 2) dp[v - 2][0] = dp[v - 2][1] = 0; 22 dp[v + 2][0] = dp[v + 2][1] = 0; 23 ans = max(ans, dp[v][0]); 24 ans = max(ans, dp[v][1]); 25 ans = max(ans, dp[v - 1][1]); 26 ans = max(ans, dp[v + 1][0]); 27 } 28 cout << ans << endl; 29 }
题C
题意:给你一副图,图里面的边都是铁路,给火车行驶,然后另外没有给出的边就是巴士行驶的,问你火车和巴士能不能都从1到达n,然后max{ t1,t2}是多少。
题解:水题,直接bfs一次即可。
1 /*zhen hao*/ 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 const int maxn = 500; 6 int G[maxn][maxn], dist[maxn]; 7 int n, m; 8 9 int bfs(int flag) { 10 memset(dist, -1, sizeof dist); 11 dist[1] = 0; 12 queue<int> Q; 13 Q.push(1); 14 while (!Q.empty()) { 15 int u = Q.front(); Q.pop(); 16 if (u == n) return dist[u]; 17 for (int i = 1; i <= n; i++) { 18 if (G[u][i] != flag) continue; 19 if (dist[i] == -1) { 20 dist[i] = dist[u] + 1; 21 Q.push(i); 22 } 23 } 24 } 25 return -1; 26 } 27 28 int main() { 29 //freopen("case.in", "r", stdin); 30 scanf("%d%d", &n, &m); 31 memset(G, 0, sizeof(G)); 32 for (int i = 0; i < m; i++) { 33 int u, v; 34 scanf("%d%d", &u, &v); 35 G[u][v] = G[v][u] = 1; 36 } 37 int t1 = bfs(0), t2 = bfs(1); 38 if (t1 == -1 || t2 == -1) puts("-1"); 39 else printf("%d\n", max(t1, t2)); 40 }
题D
题意:定义一种常数:
给你一串序列,有n个整数,然后有q个询问,每个询问是一个区间[l,r],问你这个区间的所有子区间的那个常数之和是多少,输出和;
题解:先观察这个式子可以发现,实际上j-i = 1的时候是最大的,也就是不管取什么区间都是这分母都是1,所以就是在[i,j]这个区间中的[i,i+1],[i+1,i+2]中取最大值,然后如果单纯枚举是O(n^2q),时间上行不通,最多只能跑到case10,这里用的是单调栈优化。
现在结合我的推导详细说一下这个算的过程:
我们知道单调栈的功能是快速算出左边比它大的,右边比它大的元素有多少个,也可以倒过来求左边和右边比自己小的有多少个,而且整个做法是O(n)。只要知道这个怎样套到这道题呢?我们知道区间里面的数每一个都有可能是一个子区间的最大值,那么这个次数是多少呢?看图:
(7 (8) 2 1 2)
很显然这个8倍这5个数字共享了,答案是这个8的区间一定包含了8这个元素,有多少个呢?答案是8个,8的左边有两种选择0和1,8的右边有两种选择0123,所以2*4 = 8;也就是(左边比8小的元素 +1) × (右边比8小的元素 +1);这个就是答案。然后依次用单调栈算出即可。复杂度O(nq)
1 /*zhen hao*/ 2 #include <bits/stdc++.h> 3 using namespace std; 4 5 typedef long long ll; 6 const int maxn = 1e5 + 100; 7 ll val[maxn]; 8 9 struct Node { 10 ll val; 11 int sum; 12 }; 13 14 stack<Node> S; 15 16 ll f(ll x) { 17 return x > 0 ? x : -x; 18 } 19 20 int main() { 21 // freopen("case.in", "r", stdin); 22 int n, q; 23 scanf("%d%d", &n, &q); 24 for (int i = 1; i <= n; i++) cin >> val[i]; 25 while (q--) { 26 int l, r; 27 scanf("%d%d", &l, &r); 28 ll ans = 0; 29 for (int i = l + 1; i <= r; i++) { 30 ll v = f(val[i] - val[i - 1]); 31 int temp = 0; 32 while (!S.empty() && v >= S.top().val) { 33 ans += 1LL * S.top().sum * (temp + 1) * S.top().val; 34 temp += S.top().sum; 35 S.pop(); 36 } 37 S.push((Node){v, temp + 1}); 38 } 39 int temp = 0; 40 while (!S.empty()) { 41 ans += 1LL * S.top().sum * (temp + 1) * S.top().val; 42 temp += S.top().sum; 43 S.pop(); 44 } 45 cout << ans << endl; 46 } 47 return 0; 48 }
Codeforces Round #333 (Div. 2)
原文:http://www.cnblogs.com/zhenhao1/p/5060799.html