Contestant. Rank 3134. Rating -36.
坐大牢局
A. Showstopper
题意
给定两个序列
思路
首先,既然最后方案我们无需考虑,那么我们不妨定义
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fs first
#define sc second
const int N = 2e5 + 10, inf = 0x3f3f3f3f3f3f3f3f;
void init(){}
void solve() {
int n;
cin >> n;
vector<int> a(n), b(n);
for(int i=0;i<n;i++) cin >> a[i];
for(int i=0;i<n;i++) cin >> b[i];
if(a[n - 1] > b[n - 1]) swap(a[n - 1], b[n - 1]);
bool f = true;
for(int i=0;i<n-1;i++) {
int mn = min(a[i], b[i]), mx = max(a[i], b[i]);
if (mn > a[n - 1] || mx > b[n - 1]) f = false;
}
cout << (f ? "Yes\n" : "No\n");
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
int t;
cin >> t;
while(t --) solve();
}
猜结论题 x1
B. Three Sevens
题意
给定
思路
我们不妨反过来考虑,也就是说,在后面出现的玩家一定不是前面的赢家,那么我们直接倒着遍历即可。
首先,我们遍历参加了该局的玩家,若只要有一个没被标记,那么就是有解的,我们随便输出一个即可。
然后,我们标记参加了该局的玩家,这样即可防止其在前面作为赢家。
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fs first
#define sc second
const int N = 2e5 + 10, inf = 0x3f3f3f3f3f3f3f3f;
void init(){}
void solve() {
int n;
cin >> n;
vector<vector<int>> a(n, vector<int>());
for(int i=0;i<n;i++){
int cnt;
cin >> cnt;
a[i] = vector<int>(cnt);
for(int j=0;j<cnt;j++) cin >> a[i][j];
}
vector<bool> st(50010, false);
vector<int> ans(n);
for(int i=n-1;i>=0;i--){
bool f = false;
for(auto e : a[i]){
if(!st[e]) ans[i] = e, f = true;
st[e] = true;
}
if(!f){
cout << -1 << '\n';
return;
}
}
for(auto e : ans) cout << e << ' ';
cout << '\n';
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
int t;
cin >> t;
while(t --) solve();
}
这可比A题好做多了
C. Candy Store
题意
给定
构造一组
思路
我们来考虑
首先,
其次,
所以,
显然,如果一个元素能划分到前面的序列中,那么我们完全可以不考虑它,因为就算把他放进来,不影响数量。
因此,我们可以贪心地直接遍历统计个数。
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fs first
#define sc second
const int N = 2e5 + 10, inf = 0x3f3f3f3f3f3f3f3f;
void init(){}
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b){
return a * b / gcd(a, b);
}
void solve() {
int n;
cin >> n;
vector<int> a(n), b(n);
for(int i=0;i<n;i++){
cin >> a[i] >> b[i];
}
int g = 0, l = 1, ans = 1;
for(int i=0;i<n;i++){
g = gcd(g, a[i] * b[i]);
l = lcm(l, b[i]);
if(g % l != 0){
ans ++;
g = a[i] * b[i];
l = b[i];
}
}
cout << ans << '\n';
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
int t;
cin >> t;
while(t --) solve();
}
没想到啊没想到…
D. Shocking Arrangement
题意
给定一个总和为
$\max\limits{1 \le l \le r \le n} \lvert a_l + a{l+1} + \ldots + a_r \rvert < \max(a_1, a_2, \ldots, a_n) - \min(a_1, a_2, \ldots, a_n),$
若不能满足,输出
思路
首先,我们定义
$\max\limits{1 \le l \le r \le n} \lvert a_l + a{l+1} + \ldots + ar \rvert = sum{max} - sum_{min}$。
那么,我们让 $sum{max} < \max(a_1, a_2, \ldots, a_n), sum{min} > \min(a_1, a_2, \ldots, a_n)$ 即可。
如何实现?我们不妨随便放一个数上去,然后记录当前放入的前
考虑到总和为
此时,一定有解,而若要判无解,当且仅当整个序列都是
对细节的证明
思路的第一句话是贪心的(有乱猜的嫌疑)。
为什么呢?因为,$sum{max}
或者说,
首先,根据思路,$Sx
因此得证。
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define fs first
#define sc second
const int N = 2e5 + 10, inf = 0x3f3f3f3f3f3f3f3f;
void init(){}
void solve() {
int n;
cin >> n;
stack<int> p, q;
for(int i=0;i<n;i++){
int cur;
cin >> cur;
if(cur >= 0) p.emplace(cur);
else if(cur < 0) q.emplace(cur);
}
if(q.empty()){
cout << "No\n";
return;
}
cout << "Yes\n";
int now = 0;
for(int i=0;i<n;i++){
if(now <= 0){
now += p.top();
cout << p.top() << ' ';
p.pop();
}else{
now += q.top();
cout << q.top() << ' ';
q.pop();
}
}
cout << '\n';
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
int t;
cin >> t;
while(t --) solve();
}
猜结论题 x2
- 本文链接 https://floating-ocean.github.io/blog_old/posts/302073386/
- 版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!