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;
}

队友赛时提交:传送门
从前往后的思路,考虑前到后的影响。。。(日后再理解啦~)

posted on 2023-07-28 19:32  Qiansui  阅读(6)  评论(0编辑  收藏  举报