2023牛客多校第四场 - A F L
比赛地址:传送门
赛时过了 3 题,后面无题可开,直接罚坐 3 小时
A 题意模拟
F 题意模拟
L 题意模拟
A Bobo String Construction
题意
给你一个01字符串t,让你构造一个01字符串s,使得 t + s + t 的组合字符串满足子串 t 仅出现在首尾
思路
考虑构造全 1 全 0 串,一定有一个能够满足题意,那么剩下的问题就是考虑选全 1 串还是全 0 串,这里可以用暴力判断(见下面的传送门),也可以利用 kmp 的 next 数组来求解(待解决)
代码
传送门
F Election of the King
题意
自己看题面吧。。。题面过长,懒得简述了。有空再简化啦~
思路
由题意可以,每次淘汰的一定是最左倾或者最右倾的人,那么先排序,
代码
赛时代码 又长又臭
//>>>Qiansui
void solve(){
ll n, t;
cin >> n;
vector<pll> a;
for(int i = 0; i < n; ++ i){
cin >> t;
a.push_back({t, i + 1});
}
sort(a.begin(), a.end());
ll l = 0, r = n - 1, mid;
for(int i = 1; i < n; ++ i){
ll sum = a[l].first + a[r].first;
if(sum % 2 == 0) mid = sum / 2;
else mid = (sum + 1) / 2;
auto st = upper_bound(a.begin() + l, a.begin() + r + 1, make_pair(mid, 0ll));
auto ed = upper_bound(a.begin() + l, a.begin() + r + 1, make_pair(mid, n + 1));
-- ed;
int lenr = a.begin() + r - st + 1, lenl = r - l + 1 - lenr;
if(sum % 2 == 0 && mid == st->first){
lenr -= ed - st + 1;
}
if(lenl == lenr) -- r;
else if(lenl < lenr) ++ l;
else --r;
}
cout << a[l].second << '\n';
return ;
}
简化后代码 哭了,赛时想的什么离谱代码。。。
//>>>Qiansui
void solve(){
ll n, t;
cin >> n;
vector<pll> a;
for(int i = 0; i < n; ++ i){
cin >> t;
a.push_back({t, i + 1});
}
sort(a.begin(), a.end());
ll l = 0, r = n - 1, mid;
for(int i = 1; i < n; ++ i){
mid = (l + r) / 2;
if(a[r].first - a[mid].first >= a[mid].first - a[l].first) --r;
else ++ l;
}
cout << a[l].second << '\n';
return ;
}
L We are the Lights
题意
给一个初始 $n \times m $ 的灯阵,初始所有灯均灭。现进行 q 次操作,每次操作选择一行或者一列,使得该行或者该列所有灯均灯灭或者灯亮。问你最后的亮灯数?
思路
考虑从后往前操作,因为后面的操作会覆盖前面的操作,所以从后往前,标记下已经操作的行和列,再轮到前的操作时不会对后面的操作产生影响,这样统计较为方便。
详见代码
代码
//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long
using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*
*/
const int maxm = 1e6 + 5, inf = 0x3f3f3f3f, mod = 998244353;
void solve(){
int n, m, q;
cin >> n >> m >> q;
vector<int> type(q), x(q), val(q);
for(int i = 0; i < q; ++ i){
string a, c;
int b;
cin >> a >> b >> c;
type[i] = a == "row" ? 1 : 0;
x[i] = b - 1;
val[i] = c == "on" ? 1 : 0;
}
vector<int> r(n, -1), c(m, -1);
ll ans = 0, cntr = n, cntc = m;
for(int i = q - 1; i >= 0; -- i){
if(type[i] == 0){ //column
if(c[x[i]] != -1) continue;
ans += cntr * val[i];
c[x[i]] = val[i];
-- cntc; //当前列不会再受到影响,移除它
}else{ //row
if(r[x[i]] != -1) continue;
ans += cntc * val[i];
r[x[i]] = val[i];
-- cntr; //当前行不会再受到影响,移除它
}
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
// cin >> _;
while(_ --){
solve();
}
return 0;
}
队友赛时提交:传送门
从前往后的思路,考虑前到后的影响。。。(日后再理解啦~)
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17588753.html