Codeforces Round #637 (Div. 2) 题解
A. Nastya and Rice
网址:https://codeforces.com/contest/1341/problem/A
Nastya just made a huge mistake and dropped a whole package of rice on the floor. Mom will come soon. If she sees this, then Nastya will be punished.
In total, Nastya dropped n grains. Nastya read that each grain weighs some integer number of grams from a−b to a+b, inclusive (numbers a and b are known), and the whole package of n grains weighs from c−d to c+d grams, inclusive (numbers c and d are known). The weight of the package is the sum of the weights of all n grains in it.
Help Nastya understand if this information can be correct. In other words, check whether each grain can have such a mass that the i-th grain weighs some integer number xi (a−b≤xi≤a+b), and in total they weigh from c−d to c+d, inclusive
(c−d≤sum{xi | 1 <= i <= n}≤c+d).
Input
The input consists of multiple test cases. The first line contains a single integer t (1≤t≤1000) — the number of test cases.
The next t lines contain descriptions of the test cases, each line contains 5 integers: n (1≤n≤1000) — the number of grains that Nastya counted and a,b,c,d (0≤b<a≤1000,0≤d<c≤1000) — numbers that determine the possible weight of one grain of rice (from a−b to a+b) and the possible total weight of the package (from c−d to c+d).
Output
For each test case given in the input print "Yes", if the information about the weights is not inconsistent, and print "No" if n grains with masses from a−b to a+b cannot make a package with a total mass from c−d to c+d.
Example
input
5
7 20 3 101 18
11 11 10 234 2
8 9 7 250 122
19 41 21 321 10
3 10 8 6 1
output
Yes
No
Yes
No
Yes
Note
In the first test case of the example, we can assume that each grain weighs 17 grams, and a pack 119 grams, then really Nastya could collect the whole pack.
In the third test case of the example, we can assume that each grain weighs 16 grams, and a pack 128 grams, then really Nastya could collect the whole pack.
In the fifth test case of the example, we can be assumed that 3 grains of rice weigh 2, 2, and 3 grams, and a pack is 7 grams, then really Nastya could collect the whole pack.
In the second and fourth test cases of the example, we can prove that it is impossible to determine the correct weight of all grains of rice and the weight of the pack so that the weight of the pack is equal to the total weight of all collected grains.
上下界确定即可。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n, a, b, c, d;
int main()
{
int T, vmin, vmax;
scanf("%d", &T);
while(T --)
{
vmin = 0, vmax = 0;
scanf("%d %d %d %d %d", &n, &a, &b, &c, &d);
vmin = n * (a - b), vmax = n * (a + b);
if(vmin <= c + d && vmax >= c - d) puts("Yes");
else puts("No");
}
return 0;
}
B. Nastya and Door
网址:https://codeforces.com/contest/1341/problem/B
On February 14 Denis decided to give Valentine to Nastya and did not come up with anything better than to draw a huge red heart on the door of the length k (k≥3). Nastya was very confused by this present, so she decided to break the door, throwing it on the mountains.
Mountains are described by a sequence of heights a1,a2,…,an in order from left to right (k≤n). It is guaranteed that neighboring heights are not equal to each other (that is, ai≠ai+1 for all i from 1 to n−1).
Peaks of mountains on the segment [l,r] (from l to r) are called indexes i such that l<i<r, ai−1ai+1. It is worth noting that the boundary indexes l and r for the segment are not peaks. For example, if n=8 and a=[3,1,4,1,5,9,2,6], then the segment [1,8] has only two peaks (with indexes 3 and 6), and there are no peaks on the segment [3,6].
To break the door, Nastya throws it to a segment [l,l+k−1] of consecutive mountains of length k (1≤l≤n−k+1). When the door touches the peaks of the mountains, it breaks into two parts, after that these parts will continue to fall in different halves and also break into pieces when touching the peaks of the mountains, and so on. Formally, the number of parts that the door will break into will be equal to p+1, where p is the number of peaks on the segment [l,l+k−1].
Nastya wants to break it into as many pieces as possible. Help her choose such a segment of mountains [l,l+k−1] that the number of peaks on it is maximum. If there are several optimal segments, Nastya wants to find one for which the value l is minimal.
Formally, you need to choose a segment of mountains [l,l+k−1] that has the maximum number of peaks. Among all such segments, you need to find the segment that has the minimum possible value l.
Input
The first line contains an integer t (1≤t≤\(10^4\)) — the number of test cases. Then the descriptions of the test cases follow.
The first line of each test case contains two integers n and k (3≤k≤n≤\(2⋅10^5\)) — the number of mountains and the length of the door.
The second line of the input data set contains n integers a1,a2,…,an (0≤ai≤\(10^9\), ai≠ai+1) — the heights of mountains.
It is guaranteed that the sum of n over all the test cases will not exceed \(2⋅10^5\).
Output
For each test case, output two integers t and l — the maximum number of parts that the door can split into, and the left border of the segment of length k that the door should be reset to.
Example
input
5
8 6
1 2 4 1 2 4 1 2
5 3
3 2 3 2 1
10 4
4 3 4 3 2 3 2 1 0 1
15 7
3 7 4 8 2 3 4 5 21 2 3 4 2 1 3
7 5
1 2 3 4 5 6 1
output
3 2
2 2
2 1
3 1
2 3
Note
In the first example, you need to select a segment of mountains from 2 to 7. In this segment, the indexes 3 and 6 are peaks, so the answer is 3 (only 2 peaks, so the door will break into 3 parts). It is not difficult to notice that the mountain segments [1,6] and [3,8] are not suitable since they only have a 1 peak (for the first segment, the 6 index is not a peak, and for the second segment, the 3 index is not a peak).
In the second example, you need to select a segment of mountains from 2 to 4. In this segment, the index 3 is a peak, so the answer is 2 (only 1 peak, so the door will break into 2 parts).
In the third example, you need to select a segment of mountains from 1 to 4. In this segment, the index 3 is a peak, so the answer is 2 (only 1 peak, so the door will break into 2 parts). You can see that on the segments [2,5], [4,7] and [5,8] the number of peaks is also 1, but these segments have a left border greater than the segment [1,4], so they are not the correct answer.
题目概括:定义“顶”:对于任意一个i,若满足a[i] > a[i - 1] 与 a[i] > a[i + 1],则称i为“顶点”。给定区间长度为k,要求滑动窗口,统计[L,L + k - 1]中“顶点”个数(不含区间端点),“顶点”个数最多且左端点下标最小的的区间,输出该区间的L和共有的“顶点”个数。
花O(n)统计每个位置是否是“顶”,枚举区间更新即可(一定留意:不含区间端点!!)。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn = 200000 + 15;
bool b[maxn];
int n, k, a[maxn];
int s[maxn] = {};
int main()
{
int T;
scanf("%d", &T);
while(T --)
{
memset(a, 0, sizeof(a));
memset(s, 0, sizeof(s));
memset(b, false, sizeof(b));
scanf("%d %d", &n, &k);
for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
for(int i = 2; i <= n - 1; ++ i)
{
s[i] = s[i - 1];
if(a[i] > a[i - 1] && a[i] > a[i + 1])
{
++ s[i];
b[i] = true;
}
}
int L = 1, val = -1;
for(int i = 1; i <= n; ++ i)
{
if(i + k > n + 1) break;
if(val < s[i + k - 2] - s[i])
{
L = i;
val = s[i + k - 2] - s[i];
}
}
printf("%d %d\n", val + 1, L);
}
return 0;
}
C. Nastya and Strange Generator
网址:https://codeforces.com/contest/1341/problem/C
Denis was very sad after Nastya rejected him. So he decided to walk through the gateways to have some fun. And luck smiled at him! When he entered the first courtyard, he met a strange man who was selling something.
Denis bought a mysterious item and it was... Random permutation generator! Denis could not believed his luck.
When he arrived home, he began to study how his generator works and learned the algorithm. The process of generating a permutation consists of n steps. At the i-th step, a place is chosen for the number i (1≤i≤n). The position for the number i is defined as follows:
For all j from 1 to n, we calculate rj — the minimum index such that j≤rj≤n, and the position rj is not yet occupied in the permutation. If there are no such positions, then we assume that the value of rj is not defined.
For all t from 1 to n, we calculate countt — the number of positions 1≤j≤n such that rj is defined and rj=t.
Consider the positions that are still not occupied by permutation and among those we consider the positions for which the value in the count array is maximum.
The generator selects one of these positions for the number i. The generator can choose any position.
Let's have a look at the operation of the algorithm in the following example:
Let n=5 and the algorithm has already arranged the numbers 1,2,3 in the permutation. Consider how the generator will choose a position for the number 4:
The values of r will be r=[3,3,3,4,×], where × means an indefinite value.
Then the count values will be count=[0,0,3,1,0].
There are only two unoccupied positions in the permutation: 3 and 4. The value in the count array for position 3 is 3, for position 4 it is 1.
The maximum value is reached only for position 3, so the algorithm will uniquely select this position for number 4.
Satisfied with his purchase, Denis went home. For several days without a break, he generated permutations. He believes that he can come up with random permutations no worse than a generator. After that, he wrote out the first permutation that came to mind p1,p2,…,pn and decided to find out if it could be obtained as a result of the generator.
Unfortunately, this task was too difficult for him, and he asked you for help. It is necessary to define whether the written permutation could be obtained using the described algorithm if the generator always selects the position Denis needs.
Input
The first line contains a single integer t(1≤t≤\(10^5\))
— the number of test cases. Then the descriptions of the test cases follow.
The first line of the test case contains a single integer n(1≤n≤\(10^5\))
— the size of the permutation.
The second line of the test case contains n different integers p1,p2,…,pn (1≤pi≤n) — the permutation written by Denis.
It is guaranteed that the sum of n over all test cases doesn't exceed 10^5.
Output
Print "Yes" if this permutation could be obtained as a result of the generator. Otherwise, print "No".
All letters can be displayed in any case.
Example
input
5
5
2 3 4 5 1
1
1
3
1 3 2
4
4 2 3 1
5
1 5 2 4 3
output
Yes
Yes
No
Yes
No
Note
Let's simulate the operation of the generator in the first test.
At the 1 step, r=[1,2,3,4,5],count=[1,1,1,1,1]. The maximum value is reached in any free position, so the generator can choose a random position from 1 to 5. In our example, it chose 5.
At the 2 step, r=[1,2,3,4,×],count=[1,1,1,1,0]. The maximum value is reached in positions from 1 to 4, so the generator can choose a random position among them. In our example, it chose 1.
At the 3 step, r=[2,2,3,4,×],count=[0,2,1,1,0]. The maximum value is 2 and is reached only at the 2 position, so the generator will choose this position.
At the 4 step, r=[3,3,3,4,×],count=[0,0,3,1,0]. The maximum value is 3 and is reached only at the 3 position, so the generator will choose this position.
At the 5 step, r=[4,4,4,4,×],count=[0,0,0,4,0]. The maximum value is 4 and is reached only at the 4 position, so the generator will choose this position.
In total, we got a permutation of 2,3,4,5,1, that is, a generator could generate it.
题意概括:一个序列生成器按照规则生成序列:依次考虑1~n,对于每个数i,我们为其选择在生成序列中位置,有生成的规则:
- 生成一个数组r,第j个数的值记作r[j],满足:j <= r[j] <= n,且当前生成序列当中(没有完全生成好,也就是有的位置没有生成的数),第r[j]个位置必须保证没有数生成(换句话说,若在先前操作中该位置已经填上了数了,那么r[j]不可以是该位置的下标),同时r[j]须越小越好(如果3、4和5均可,则选择3,因为值最小)。
- 再生成count数组,记录r数组中每一个值的个数。譬如:r[3] = {2, 2, 3},则count[4] = {0, 2, 1}(统计出现次数)。
- 言归正传,在生成环节结束后(r和count数组生成完毕了),对于i生成的位置,该位置为count数组中数最大的位置的下标(如果count[4]最大,该数应填在生成序列中的第四个),若有多个位置下的值满足,则在其中选择任意一个位置。
给定一个序列p,求是否可以按上述规律生成p。
题意挺绕,只要静心模拟一下,变可以发现规律:题目其实就是想问区间是否“连续”。
称这样的序列为“连续”:456|123、123456、89|567|1234。(留意分出的子序列的共同点)而这样的序列:
123465、41235、132则不满足题意。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 100000 + 10;
bool valid;
int n, p[maxn], a[maxn], head, tail;
int main()
{
int T;
scanf("%d", &T);
while(T --)
{
scanf("%d", &n);
for(int i = 1; i <= n; ++ i)
{
scanf("%d", &p[i]);
a[p[i]] = i;
}
head = a[1], tail = n;
valid = true;
for(int i = 1; i <= n; ++ i)
{
if(a[i] != a[i - 1] + 1 && a[i] != head)
{
valid = false;
break;
}
if(a[i] == tail)
{
tail = head - 1;
head = a[i + 1];
}
}
if(valid) puts("Yes");
else puts("No");
}
return 0;
}
D. Nastya and Scoreboard
网址:https://codeforces.com/contest/1341/problem/D
Denis, after buying flowers and sweets (you will learn about this story in the next task), went to a date with Nastya to ask her to become a couple. Now, they are sitting in the cafe and finally... Denis asks her to be together, but ... Nastya doesn't give any answer.
The poor boy was very upset because of that. He was so sad that he punched some kind of scoreboard with numbers. The numbers are displayed in the same way as on an electronic clock: each digit position consists of 7 segments, which can be turned on or off to display different numbers. The picture shows how all 10 decimal digits are displayed:
After the punch, some segments stopped working, that is, some segments might stop glowing if they glowed earlier. But Denis remembered how many sticks were glowing and how many are glowing now. Denis broke exactly k segments and he knows which sticks are working now. Denis came up with the question: what is the maximum possible number that can appear on the board if you turn on exactly k sticks (which are off now)?
It is allowed that the number includes leading zeros.
Input
The first line contains integer n (1≤n≤2000) — the number of digits on scoreboard and k (0≤k≤2000) — the number of segments that stopped working.
The next n lines contain one binary string of length 7, the i-th of which encodes the i-th digit of the scoreboard.
Each digit on the scoreboard consists of 7 segments. We number them, as in the picture below, and let the i-th place of the binary string be 0 if the i-th stick is not glowing and 1 if it is glowing. Then a binary string of length 7 will specify which segments are glowing now.
Thus, the sequences "1110111", "0010010", "1011101", "1011011", "0111010", "1101011", "1101111", "1010010", "1111111", "1111011" encode in sequence all digits from 0 to 9 inclusive.
Output
Output a single number consisting of n digits — the maximum number that can be obtained if you turn on exactly k sticks or −1, if it is impossible to turn on exactly k sticks so that a correct number appears on the scoreboard digits.
Examples
input
1 7
0000000
output
8
input
2 5
0010010
0010010
output
97
input
3 5
0100001
1001001
1010011
output
-1
Note
In the first test, we are obliged to include all 7 sticks and get one 8 digit on the scoreboard.
In the second test, we have sticks turned on so that units are formed. For 5 of additionally included sticks, you can get the numbers 07, 18, 34, 43, 70, 79, 81 and 97, of which we choose the maximum — 97.
In the third test, it is impossible to turn on exactly 5 sticks so that a sequence of numbers appears on the scoreboard.
这道题我使用将每个数码亮灯情况转化为二进制数(预处理十个数码的状态),状态压缩,记忆化搜索。
留意:算状态A亮多少盏灯变成状态B,不可直接把两个数异或运算,因为A中有些灯需要熄灭才能成为B,而这不合题意。
代码如下:
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn = 2000 + 5;
const int d_code[10] = {119, 18, 93, 91, 58, 107, 111, 82, 127, 123};//预处理十个数码
int n, k, p[maxn], d[maxn][maxn] = {-1};
vector <int> a;
int calc(int x, int y)
{
int T = 0;
for(int i = 0; i < 7; ++ i)
{
if(y & (1 << i) && !(x & (1 << i))) return -1;
if(x & (1 << i) && !(y & (1 << i))) ++ T;
}
return T;
}
bool dfs(int cur, int m)
{
if(cur == n)
{
if(m > 0) return false;
for(int i = 0; i < a.size(); ++ i) printf("%d", a[i]);
puts("");
return true;
}
int &ans = d[cur][m];
if(ans != -1) return ans;//记忆化
bool ok = false;
for(int i = 9; i >= 0; -- i)
{
int num = calc(d_code[i], p[cur]);
if(num == -1) continue;
if(num > m) continue;
a.push_back(i);
ok = dfs(cur + 1, m - num);
a.pop_back();
if(ok) return ans = 1;
}
return ans = 0;
}
int main()
{
memset(d, -1, sizeof(d));
memset(p, 0, sizeof(p));
a.clear();
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++ i)
{
int op;
for(int j = 0; j < 7; ++ j)
{
scanf("%1d", &op);
p[i] = (p[i] << 1) + op;
}
}
if(!dfs(0, k)) puts("-1");
return 0;
}
本题有DP做法:预处理cnt[i, j]代表第i个数码初始状态变成数字j所需要亮灯的数量(熄灯不可以),dp[i, j]代表考虑第i个数码到剩余数码时,还需要严格的点亮j盏灯的可行性。
dp[i, j] |= dp[i - 1, j - cnt[i][x]]。我的代码中将整个数码顺序颠倒下。
最后结果:贪心也可以,利用dp数组逆推也行(我代码采用这一种方式)。
代码如下:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 2000 + 5;
const int d_code[10] = {119, 18, 93, 91, 58, 107, 111, 82, 127, 123};
int n, k, p[maxn], cnt[maxn][10], f[maxn][maxn];
bool dp[maxn][maxn];
int calc(int x, int y)
{
int T = 0;
for(int i = 0; i < 7; ++ i)
{
//当前状态下的某位 亮灯 但是目标在该位置下 没有亮灯,就不符合题意。
if(y & (1 << i) && !(x & (1 << i))) return 2505;//如果赋INF啦,会WA
if(x & (1 << i) && !(y & (1 << i))) ++ T;
}
return T;
}
int main()
{
memset(p, 0, sizeof(p));
memset(dp, false, sizeof(dp));
scanf("%d %d", &n, &k);
for(int i = 1; i <= n; ++ i)
{
int op;
for(int j = 0; j < 7; ++ j)
{
scanf("%1d", &op);
p[i] = (p[i] << 1) + op;
}
}
reverse(p + 1, p + n + 1);
for(int i = 1; i <= n; ++ i)
for(int j = 0; j < 10; ++ j) cnt[i][j] = calc(d_code[j], p[i]);
dp[0][0] = true;
for(int i = 1; i <= n; ++ i)
{
for(int j = 0; j <= k; ++ j)
{
for(int x = 0; x < 10; ++ x)
{
if(j >= cnt[i][x])
{
dp[i][j] |= dp[i - 1][j - cnt[i][x]];
if(dp[i - 1][j - cnt[i][x]]) f[i][j] = x;
}
}
}
}
if(dp[n][k])
{
int now = k;
for(int i = n; i > 0; -- i)
{
printf("%d", f[i][now]);
now -= cnt[i][f[i][now]];
}
}
else puts("-1");
return 0;
}
Codeforces Round #637 (Div. 2) 题解的更多相关文章
- Codeforces Round #182 (Div. 1)题解【ABCD】
Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...
- Codeforces Round #608 (Div. 2) 题解
目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...
- Codeforces Round #525 (Div. 2)题解
Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...
- Codeforces Round #528 (Div. 2)题解
Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...
- Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...
- Codeforces Round #677 (Div. 3) 题解
Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...
- Codeforces Round #665 (Div. 2) 题解
Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...
- Codeforces Round #160 (Div. 1) 题解【ABCD】
Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...
- Codeforces Round #383 (Div. 2) 题解【ABCDE】
Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...
随机推荐
- .net跨域接口服务器端配置
在项目Config文件中添加一下节点配置 <system.webServer> <httpProtocol> <customHeaders> <add nam ...
- ubuntu 虚拟机复制后打开蓝屏解决办法
sudo apt-get install xserver-xorg-lts-utopic sudo dpkg-reconfigure xserver-xorg-lts-utopic reboot
- Java入门第一阶段总结
前言 写了三周的模拟题,对原本就厌恶的模拟更加深恶痛绝.但是不得不说模拟题是对一门语言入门掌握其语法成效最快的一类题,轻松地从C入门到了Java.一直坚信各门语言都是想通的,一力破万法. 作业过程总结 ...
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析
Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析 本文简要介绍了基于 Spring 的 web project 的启动流程,详细分析了 Spring 框架将开发人员基于 XML ...
- Python 应用领域及学习重点
笔者认为不管学习什么编程语言,首先要知道:学完之后在未来能做些什么? 本文将浅谈 Python 的应用领域及其在对应领域的学习重点.也仅是介绍了 Python 应用领域的"冰山一角" ...
- Python-元组tuple、列表list、字典dict
1.元组tuple(1)元组是有序列表,有不可见的下标,下标从0开始(2)元组的数据是相对固定的,数据不能增删改,他的一个重要用途是保存固定的.安全要求高的数据(3)元组用小括号()括起来,空元组定义 ...
- Cobalt Strike系列教程第六章:安装扩展
Cobalt Strike系列教程分享如约而至,新关注的小伙伴可以先回顾一下前面的内容: Cobalt Strike系列教程第一章:简介与安装 Cobalt Strike系列教程第二章:Beacon详 ...
- nginx配置虚拟主机、反向代理和负载均衡
为了实现这个功能,需要修改nginx的配置文件,将nginx.conf清理一下,使结构更清晰. worker_processes ; events { worker_connections ; } h ...
- Java实现链表(个人理解链表的小例子)
1.单链表和数组的区别 数组:数组的存储空间是连续的,需要事先申请空间确定大小,通过下标查找数据,所以查找速度快,但是增加和删除速度慢 链表:离散存储,不需要事先确定大小,通过头指针加遍历查找数据,查 ...
- Java IO 流--FileUtils 工具类封装
IO流的操作写多了,会发现都已一样的套路,为了使用方便我们可以模拟commosIo 封装一下自己的FileUtils 工具类: 1.封装文件拷贝: 文件拷贝需要输入输出流对接,通过输入流读取数据,然后 ...