题解题目:CodeForces - 602B CodeForces - 717E CodeForces - 746G
Codeforce 602B Approximating a Constant Range
When Xellos was doing a practice course in university, he once had to measure the intensity of an effect that slowly approached equilibrium. A good way to determine the equilibrium intensity would be choosing a sufficiently large number of consecutive data points that seems as constant as possible and taking their average. Of course, with the usual sizes of data, it's nothing challenging — but why not make a similar programming contest problem while we're at it?
You're given a sequence of n data points a1, ..., an. There aren't any big jumps between consecutive data points — for each 1 ≤ i < n, it's guaranteed that |ai + 1 - ai| ≤ 1.
A range [l, r] of data points is said to be almost constant if the difference between the largest and the smallest value in that range is at most 1. Formally, let M be the maximum and m the minimum value of ai for l ≤ i ≤ r; the range [l, r] is almost constant if M - m ≤ 1.
Find the length of the longest almost constant range.
Input
The first line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of data points.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 100 000).
Output
Print a single number — the maximum length of an almost constant range of the given sequence.
Examples
input
Copy
5
1 2 3 3 2
output
Copy
4
input
Copy
11
5 4 5 5 6 7 8 8 8 7 6
output
Copy
5
Note
In the first sample, the longest almost constant range is [2, 5]; its length (the number of data points in it) is 4.
In the second sample, there are three almost constant ranges of length 4: [1, 4], [6, 9] and [7, 10]; the only almost constant range of the maximum length 5 is [6, 10].
输入的数组相邻两个元素 abs(a[i] - a[i+1]) <= 1, 求最长区间长度使得 此区间的 amax - amin <= 1
直接贴代码
方法一 dp
using namespace std;
const int MaxN = 1e5 + 10;
map<int, int> mp;
int main() {
int n, gg, ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &gg);
if(mp[gg - 1] > mp[gg + 1]) ans = max(ans, i - max(mp[gg - 2], mp[gg + 1])); // gg-1 and gg
else ans = max(ans, i - max(mp[gg - 1], mp[gg + 2])); //gg+1 and gg
mp[gg] = i;
}
printf("%d
", ans);
return 0;
}
方法二 采用multiset
using namespace std;
//priority_queue<int,vector<int>, greater<int> > pq;
//set<int>::iterator it;
const int inf = 0x3f3f3f3f;
const int MaxN = 1e5 + 10;
int a[MaxN];
multiset<int> st;
int main() {
int n, pp, l = 1, ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) {
st.insert(a[i]);
if(abs(*st.begin()-*st.rbegin()) > 1) st.erase(st.find(a[l++]));
//不满足则依次删左边的 改成while()一样的效果,while更加容易理解
ans = max(ans, (int)st.size());
}
printf("%d
", ans);
}
set 与 multiset 区别是set中没有相同元素 而 multiset有相同元素 均会 自动排序
st.erase(元素) 则会将所有这个相同元素山区, 而st.erase(st.find(元素)) 只会删一个元素
又随便写了个
const int MaxN = 1e5 + 10;
int a[MaxN], p[MaxN];
int main() {
int n, ans = 2, l = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
p[a[1]] = 1, p[a[2]] = 2;
int m = min(a[1], a[2]);
for(int i = 3; i <= n; i++) {
if(a[i] < m) { //m-1
l = p[m+1];
m = a[i];
}
else if(a[i] > m + 1) { // m + 2
l = p[m];
m = m + 1;
}
p[a[i]] = i;
ans = max(ans ,i - l);
}
printf("%d
", ans);
}
E. Paint it really, really dark gray
I see a pink boar and I want it painted black. Black boars look much more awesome and mighty than the pink ones. Since Jaggy became the ruler of the forest, he has been trying his best to improve the diplomatic relations between the forest region and the nearby ones.
Some other rulers, however, have requested too much in return for peace between their two regions, so he realized he has to resort to intimidation. Once a delegate for diplomatic relations of a neighboring region visits Jaggy’s forest, if they see a whole bunch of black boars, they might suddenly change their mind about attacking Jaggy. Black boars are really scary, after all.
Jaggy’s forest can be represented as a tree (connected graph without cycles) with n vertices. Each vertex represents a boar and is colored either black or pink. Jaggy has sent a squirrel to travel through the forest and paint all the boars black. The squirrel, however, is quite unusually trained and while it traverses the graph, it changes the color of every vertex it visits, regardless of its initial color: pink vertices become black and black vertices become pink.
Since Jaggy is too busy to plan the squirrel’s route, he needs your help. He wants you to construct a walk through the tree starting from vertex 1 such that in the end all vertices are black. A walk is a sequence of vertices, such that every consecutive pair has an edge between them in a tree.
Input
The first line of input contains integer n (2 ≤ n ≤ 200 000), denoting the number of vertices in the tree. The following n lines contains nintegers, which represent the color of the nodes.
If the i-th integer is 1, if the i-th vertex is black and - 1 if the i-th vertex is pink.
Each of the next n - 1 lines contains two integers, which represent the indexes of the vertices which are connected by the edge. Vertices are numbered starting with 1.
Output
Output path of a squirrel: output a sequence of visited nodes' indexes in order of visiting. In case of all the nodes are initially black, you should print 1. Solution is guaranteed to exist. If there are multiple solutions to the problem you can output any of them provided length of sequence is not longer than 107.
Example
input
Copy
5
1
1
-1
1
-1
2 5
4 3
2 4
4 1
output
Copy
1 4 2 5 2 4 3 4 1 4 1
Note
At the beginning squirrel is at node 1 and its color is black. Next steps are as follows:
- From node 1 we walk to node 4 and change its color to pink.
- From node 4 we walk to node 2 and change its color to pink.
- From node 2 we walk to node 5 and change its color to black.
- From node 5 we return to node 2 and change its color to black.
- From node 2 we walk to node 4 and change its color to black.
- We visit node 3 and change its color to black.
- We visit node 4 and change its color to pink.
- We visit node 1 and change its color to pink.
- We visit node 4 and change its color to black.
- We visit node 1 and change its color to black.
题意:每个点都有一个值为1或-1,每当走过一个点就变化 *-1 , 我们的目的是让所有的点都变为1,然后输出路径。 开始在第一个点。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#define pi acos(-1.0)
#define mod 998244353
#define pb push_back
using namespace std;
//priority_queue<int,vector<int>, greater<int> > pq;
//set<int>::iterator it;
const int inf = 0x3f3f3f3f;
const int MaxN = 2e5 + 10;
vector<int> g[MaxN], ans;
int a[MaxN], n, vis[MaxN];
void dfs(int x, int f) {
for(int i = 0; i < g[x].size(); i++) {
int u = g[x][i];
if(u == f) continue;
a[u] = a[u] * -1;
ans.pb(u); //将当前点压入ans
dfs(u, x);
ans.pb(x); //回溯 将父亲压入ans
a[x] = a[x] * -1;
if(a[u] == -1) { //若此时改变后为-1的处理
a[u] = 1, ans.pb(u);
a[x] = a[x] * -1, ans.pb(x);
}
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
g[u].pb(v);
g[v].pb(u);
}
ans.pb(1);
dfs(1, 0);
if(a[1] == -1)
ans.pb(g[1][0]), ans.pb(1), ans.pb(g[1][0]);
for(int i = 0; i < ans.size(); i++) {
if(i==0) printf("%d", ans[i]);
else printf(" %d", ans[i]);
}
printf("
");
}