Skip to content

Commit 833d857

Browse files
committed
update Starter72B (Rated for div2).md
1 parent db6374c commit 833d857

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

Diff for: codeforces/contest/Codeforces Round #842 (Div. 2).md

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# [Codeforces Round #842 (Div. 2)](https://codeforces.com/contest/1768)
2+
3+
4+
5+
## A
6+
7+
观察到 **i! + (i-1)! = (i+1)*(i-1)!**,所以能保证的最大值为`k-1`
8+
9+
```cpp
10+
void solve() {
11+
ll k;
12+
cin >> k;
13+
//(i-1)!*(i+1)
14+
//(i^2-1)*(i-2)
15+
cout << k-1 << "\n";
16+
}
17+
18+
```
19+
20+
21+
22+
## B
23+
24+
由于该操作会影响顺序,其实我们只需要考虑递增的最长子序列即可
25+
26+
```cpp
27+
void solve() {
28+
int n, k;
29+
cin >> n >> k;
30+
vector <int> id(n+1);
31+
for (int i = 1; i <= n; i++) {
32+
int x;
33+
cin >> x;
34+
id[x] = i;
35+
}
36+
int t = 2;
37+
while (t <= n && id[t] > id[t-1]) t++;
38+
cout << (n - t + k) / k << "\n"; //注意此处ceil需要写成(n-1+t+k)/k之类的形式来计算
39+
}
40+
```
41+
42+
43+
44+
## C
45+
46+
贪心,首先1的话由于特殊性,只能出现最多一次,其他数字可以出现最多两次。
47+
48+
然后,贪心地先填小的数字,因为先填大的会导致后面的选择变少
49+
50+
```cpp
51+
void solve() {
52+
int n;
53+
cin >> n;
54+
vector <int> a(n+1), st(n+1);
55+
vector <vector<int>> ans(2, vector<int>(n+1)), has(2, vector <int> (n+1, 1));
56+
vector <int> pos(2, 1);
57+
priority_queue <tp,vector<tp>,greater<>> q;
58+
for (int i = 1; i <= n; i++) {
59+
cin >> a[i];
60+
}
61+
for (int i = 1; i <= n; i++) {
62+
st[a[i]]++;
63+
if (st[a[i]] > 2 || st[1] >= 2) {
64+
cout << "NO\n";
65+
return;
66+
}
67+
ans[st[a[i]]-1][i] = a[i];
68+
has[st[a[i]]-1][a[i]] = 0;
69+
q.emplace(a[i], st[a[i]]-1, i);
70+
}
71+
// 贪心,每次都填最小的
72+
while (q.size()) {
73+
auto [val, p, id] = q.top(); q.pop();
74+
int & x = pos[!p];
75+
while (x <= n && !has[!p][x]) x++;
76+
if (x > val) {
77+
cout << "NO\n";
78+
return;
79+
}
80+
ans[!p][id] = x;
81+
x++;
82+
}
83+
cout << "YES\n";
84+
for (int i = 0; i < 2; i++) {
85+
for (int j = 1; j <= n; j++) {
86+
cout << ans[i][j] << " ";
87+
}
88+
cout << "\n";
89+
}
90+
}
91+
```
92+
93+
## D
94+
95+
需要观察出以下性质:
96+
97+
1. 满足条件的序列只有n-1个,是从升序排序的序列里头挑出来相邻的两个进行逆序操作
98+
2. 将一个打乱的序列恢复成升序排序的操作数为 **n-cycles**,其中 **cycles**为置换环的数目
99+
3. 从升序序列变成满足条件的序列,如果相邻点不在一个集合内部的话,则需要额外的操作一次达到逆置;反之如果在一个集合内部的话,则操作数减一
100+
101+
```cpp
102+
void solve() {
103+
int n;
104+
cin >> n;
105+
vector <int> id(n + 1), st(n + 1);
106+
for (int i = 1; i <= n; i++) {
107+
int x;
108+
cin >> x;
109+
id[x] = i;
110+
}
111+
int ans = n;
112+
for (int i = 1; i <= n; i++) {
113+
if (st[i]) continue;
114+
int j = i;
115+
while (!st[j]) {
116+
st[j] = i;
117+
j = id[j];
118+
}
119+
ans--;
120+
}
121+
for (int i = 2; i <= n; i++) {
122+
if (st[i] == st[i - 1]) {
123+
cout << ans - 1 << "\n";
124+
return;
125+
}
126+
}
127+
cout << ans + 1 << "\n";
128+
}
129+
```
130+
131+
132+
133+
134+
135+
## 小结
136+
137+
构造题做得不够,思维比较僵化

0 commit comments

Comments
 (0)