题解:Codeforces Round 960 (Div. 2) B
B. Array Craft
time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output
For an array \(b\) of size \(m\), we define:
- the maximum prefix position of \(b\) is the smallest index \(i\) that satisfies \(b_1+\ldots+b_i=\max_{j=1}^{m}(b_1+\ldots+b_j)\);
- the maximum suffix position of \(b\) is the largest index \(i\) that satisfies \(b_i+\ldots+b_m=\max_{j=1}^{m}(b_j+\ldots+b_m)\).
You are given three integers \(n\), \(x\), and \(y\) (\(x \gt y\)). Construct an array \(a\) of size \(n\) satisfying:
- \(a_i\) is either \(1\) or \(-1\) for all \(1 \le i \le n\);
- the maximum prefix position of \(a\) is \(x\);
- the maximum suffix position of \(a\) is \(y\).
If there are multiple arrays that meet the conditions, print any. It can be proven that such an array always exists under the given conditions.
对于大小为 \(m\) 的数组 \(b\) ,我们可以这样定义:
- \(b\) 的最大前缀位置是满足 \(b_1+\ldots+b_i=\max_{j=1}^{m}(b_1+\ldots+b_j)\) 的最小索引 \(i\) ;
- \(b\) 的最大后缀位置是满足 \(b_i+\ldots+b_m=\max_{j=1}^{m}(b_j+\ldots+b_m)\) 的大索引 \(i\) 。
给你三个整数 \(n\) 、 \(x\) 和 \(y\) ( \(x \gt; y\) )。请构造一个大小为 \(n\) 的数组 \(a\) 满足以下条件:
- 对于所有 \(1 \le i \le n\) , \(a_i\) 要么是 \(1\) 要么是 \(-1\) ;
- \(a\) 的个最大前缀位置是 \(x\) ;
- \(a\) 的最大后缀位置是 \(y\) 。
如果有多个数组满足条件,则打印任意一个。可以证明,在给定的条件下,这样的数组总是存在的。
对于大小为 \(m\) 的数组 \(b\) ,我们可以定义: \(b\) 的最大前缀位置是满足 \(b_1+\ldots+b_i=\\max_{j=1}^{m}(b_1+\ldots+b_j)\) 的最小索引 \(i\) ; \(b\) 的最大后缀位置是满足 \(b_i+\ldots+b_m=\\max_{j=1}^{m}(b_j+\ldots+b\_m)\) 的最大索引 \(i\) 。给你三个整数 \(n\) 、 \(x\) 和 \(y\) ( \(x > y\) )。构造一个大小为 \(n\) 的数组 \(a\) 满足: - 对于所有的 \(1 \le i \le n\) 来说, \(a_i\) 要么是 \(1\) 要么是 \(-1\) ; \(a\) 的最大前缀位置是 \(x\) ; - \(a\) 的最大后缀位置是 \(y\) 。如果有多个数组满足条件,请打印任意一个。可以证明,在给定的条件下,这样的数组总是存在的。
Input
The first line contains an integer \(t\) (\(1 \leq t \leq 10^4\)) — the number of test cases.
For each test case:
- The only line contains three integers \(n\), \(x\), and \(y\) (\(2 \leq n \leq 10^5, 1 \le y \lt x \le n)\).
It is guaranteed that the sum of \(n\) over all test cases will not exceed \(10^5\).
输入
第一行包含一个整数 \(t\) ( \(1 \leq t \leq 10^4\) ) - 测试用例的数量。
对于每个测试用例
- 唯一一行包含三个整数 \(n\) 、 \(x\) 和 \(y\) ( \(2 \leq n \leq 10^5, 1 \le y \lt x \le n)\) .
保证所有测试用例中 \(n\) 的总和不超过 \(10^5\) 。
Output
For each test case, output \(n\) space-separated integers \(a_1, a_2, \ldots, a_n\) in a new line.
输出
对于每个测试用例,在新行中输出 \(n\) 个空格分隔的整数 \(a_1, a_2, \ldots, a_n\) 。
Example
input
3
2 2 1
4 4 3
6 5 1
output
1 1
1 -1 1 1
1 1 -1 1 1 -1
Note
In the second test case,
- \(i=x=4\) is the smallest index that satisfies \(a_1+\ldots +a_i=\max_{j=1}^{n}(a_1+\ldots+a_j)=2\);
- \(i=y=3\) is the greatest index that satisfies \(a_i+\ldots +a_n=\max_{j=1}^{n}(a_j+\ldots+a_n)=2\).
Thus, the array \(a=[1,-1,1,1]\) is considered correct.
注
在第二个测试案例中
- \(i=x=4\) 是满足 \(a_1+\ldots +a_i=\max_{j=1}^{n}(a_1+\ldots+a_j)=2\) 的小索引;
- \(i=y=3\) 是满足 \(a_i+\ldots +a_n=\max_{j=1}^{n}(a_j+\ldots+a_n)=2\) 的大索引。
因此,数组 \(a=[1,-1,1,1]\) 被认为是正确的。
我的题解
分类讨论一下
-
- 假如 \(x \lt y\) ,那就是两个区间之间没有交集了,要使左边到x最大,就是要到 \(x\) 的右边会变小;同理,要使右边到 \(y\) 最大,就是要到y的左边会变小。
- 因此,在我只要让 \(x\) 到 \(y\) 的中间部分全部为 \(-1\),然后从 \(x-1\) 开始一直到 \(0\) 交替为 \(1,-1,1,-1,...\) ,同样的,从 \(y+1\) 开始一直到 \(n\) 交替为 \(1,-1,1,-1,...\),这样让两边的区间和趋于0,同时又不会说边界被选到除了 \(x\) 和 \(y\) 的其他位置。
-
- 假如 \(x \gt y\) ,那就是两个区间之间有交集
- 因此,在我只要让 \(x\) 到 \(y\) 的中间部分全部为 \(1\),然后从 \(x-1\) 开始一直到 \(0\) 交替为 \(-1,1,-1,...\) ,同样的,从 \(y+1\) 开始一直到 \(n\) 交替为 \(-1,1,-1,...\),这样让两边的区间和趋于0,同时又不会说边界被选到除了 \(y\) 和 \(x\) 的其他位置。
但是!
虽然但是总感觉这样有点漏洞,直到我看到了题目数据范围,\(1 \le y \lt x \le n\),我才知道我想多了,只用算第二种情况,那就是绝对无误的
别急!
假设我们包含第一种情况吧,我为什么会觉得 \(x \lt y\) 会有点问题呢,因为我想到了加入 \(x + 1 = y\) 的话怎么办,这样的话我的程序出来就是错的了。
但是!
我忽然想到,假如真的出现 \(x + 1 = y\) 的情况的话,那么 \(x\) 就不应该是在 \(x\) 这个位置上,应该比 \(x\) 大, \(y\) 也不应该是在 \(y\) 这个位置上,应该比 \(y\) 小!
结论:
我的思路是正确的!
我的代码
#include <bits/stdc++.h>
#define int long long
const int N = 1e7 + 10;
int t;
int a[N];
void solve() {
int n,x,y;
std::cin >> n >> x >> y;
int jud = -1;
if(x > y) {
std::swap(x,y);
jud *= (-1);
}
if(jud == -1) {
for(int i = x ; i <= y ; i ++) a[i] = 1;
x--;
while(x-1 >= 0) a[x] = -1, x--;
y++;
while(n-y >= 0) a[y] =-1,y++;
}
else {
for(int i = x ; i <= y ; i ++) a[i] = 1;
for(int i = x-1 ; i > 0 ; i --) a[i] = ((x-i)&1 ? -1 : 1);
for(int i = y+1 ; i <= n ; i ++) a[i] = ((i-y)&1 ? -1 : 1);
}
for(int i = 1 ; i <= n ;i ++) std::cout << a[i] << " ";
std::cout << "\n";
}
signed main() {
std::cin >> t;
while(t--) {
solve();
}
return 0;
}
简化版
把 if-else 那部分只保留else就可以了
posted on 2024-07-21 11:16 Jiejiejiang 阅读(97) 评论(0) 编辑 收藏 举报