2024牛客寒假算法基础集训营1

2024寒假集训1 传送门

1.DFS搜索

题意

给一个一个字符串和它的长度 需要你判断存不存在一个子序列“DFS” or "dfs"

思路

双指针扫两遍

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
#define deb(x) cout << #x << " = " << x << '\n';
#define INF 0x3f3f3f3f
using namespace std;
void solve()
{
	int n; cin >> n;
	string st; cin >> st;
	string mod[2] = { "DFS","dfs" };
	for (auto t : mod)
	{
		int k = 0;
		for (int i = 0; i < n; i++)
			if (k < 3 && st[i] == t[k]) k++;
		cout << (k == 3) << ' ';
	}
    puts("");
}

signed main()
{
//     IOS;
	int t = 1; cin >> t;
	while (t--) solve();
    return 0;
}

B.关鸡

题意

给你一个 2 * 2e9  的矩阵

鸡哥在(1,0)的位置 鸡哥想跑出这个矩阵但鸡哥怕火

开始的时候会有一些火并告诉你它们的坐标

鸡哥只能上下左右的跑 问你要加多少个火可以组织鸡哥跑出这个矩阵 

思路

1. 一般情况:

(1)统计左边右边有没有堵上 都堵上输出0

(2)若只有一边堵上 判断另一边有没有火

I.有火的话只需要输出1 

II. 没有火需要判断有没有(2,0)这个特殊点 如果也没有就输出2 有就输出1

(3)两边都没火就判断有没有(2,0)如果有输出2 无输出3

2.特殊情况:

(1)如果有三角形结构的墙(1,-1),(1,1),(2,0)输出0

(2)如果有(1,-1),(1,1) 输出1

(3)如果有(1,-1) 或 (1,1)输出2 (这里分成两种情况但答案都是2,即使另一边有没有都是2个)

(4)如果都没有就看一边有没有火 

I.有火 再看另一边有没有 有就输出2 没有再判断中间(2,0)有没有 有2 没有3

II.没有火 再看另一边有没有 同上

写了207-128 mn😾😾

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//typedef pair<char, int> PCI;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int dx[5] = {1,1,-1,-1}, dy[5] = {1,0,1,0};
//const int N = 2e5 + 10;
int n, m, cnt;
PII a[N];
int tmp[N];
void solve()
{
	map<PII,bool> mp;
	int n; cin >> n;
	int exl = 0, exr = 0;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i].first >> a[i].second;
		if (a[i].second < 0) exl = 1;
		if (a[i].second > 0) exr = 1;
		mp[{a[i].first,a[i].second}] = true;
	}
	if (n == 0)
	{
		cout << 3 << endl;
		return;
	}
	int flag1 = 0, flag2 = 0;
	for (int i = 1; i <= n; i++)
	{
		int x = a[i].first, y = a[i].second;
		if (flag1 && y < 0) continue;
		if (flag2 && y >= 0) continue;
		for (int j = 0; j < 4; j++)
		{
			int nx = x + dx[j], ny = y + dy[j];
			if (!mp[{nx,ny}]) continue;
			if (y < 0) flag1 = 1;
			if (y >= 0) flag2 = 1;// 不出意外就已经吧三角形搞掉了
		}
	}
	if (flag1 && flag2) cout << 0 << endl;
	else if (flag1)
	{
		if (exr) cout << 1 << endl;
		else
		{
			if (mp[{2, 0}]) cout << 1 << endl;
			else cout << 2 << endl;
		}
	}
	else if (flag2)
	{
		if (exl) cout << 1 << endl;
		else
		{
			if (mp[{2, 0}]) cout << 1 << endl;
			else cout << 2 << endl;
		}
	}
	else
	{
		if (mp[{1, -1}] && mp[{1, 1}]) cout << 1 << endl;
		else if (mp[{1, -1}] || mp[{1, 1}]) cout << 2 << endl;
		else
		{
			if (exl)
			{
				if (exr) cout << 2 << endl;
				else
				{
					if (mp[{2, 0}]) cout << 2 << endl;
					else cout << 3 << endl;
				}
			}
			else
			{
				if (exl) cout << 2 << endl;
				else
				{
					if (mp[{2, 0}]) cout << 2 << endl;
					else cout << 3 << endl;
				}
			}
		}
	}
}

signed main()
{
	//IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

C.按闹分配

题意

有n个人排队办事,每个人需要ti个单位的时间

时刻0所有人进入办事大厅,第i个人的不满意度为Di 指的是他办完这件事的时刻

所有人总不满意度 S = \sum_{i=1}^{n} D_i

工作人员会想办法安排办事顺序使总不满意度最小,记为S_{min}

现在有一只很急的鸡来办事,它可以在任意时刻要求工作人员放下手头的事情来处理它的事情

这只鸡需要t_c的时间办理,假设鸡插队后其余n人的总不满意度最小值变为S_c

当满足:S_c - S_{min} \leq M 工作人员将允许鸡插队,否则拒绝。M指的是工作人员的忍耐度

现在有Q组询问 给出不同员工的忍耐度M 问鸡最早能什么时候办完事

思路1

极其暴力的算 3个前缀和1个后缀和。其实不需要这样

要注意的是 实操一下 不管鸡是在那个人办事的时候插队还是还没开始的那一瞬间插队 后面的Sc是一样的。

另外,S_{min}=从小到大的忍耐度之和

code1

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int dx[5] = { 1,1,-1,-1 }, dy[5] = { 1,0,1,0 };
int n, m, cnt;
int a[N], sum[N], res[N], zui[N], sumz[N];
void solve()
{
	int n, q, tc; cin >> n >> q >> tc;
	for (int i = 1; i <= n; i++) cin >> a[i];
	sort(a + 1, a + 1 + n);
	// sum[i]是不耐烦值
	for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i];
	// sumz[i]是不耐烦值的和
	for (int i = 1; i <= n; i++) sumz[i] = sumz[i - 1] + sum[i];
	// 最初的sm就是sumz[n]
	int sm = sumz[n], m = 0;
	// res[i]是插队后队伍的不耐烦
	res[n + 1] = 0;
	for (int i = n; i >= 1; i--) res[i] = res[i + 1] + sum[i] + tc;
	// zui[i]是选择插入哪里 前面不耐烦和后面不耐烦相加  from 0 开始!!
	for (int i = 0; i < n; i++) zui[i] = sumz[i] + res[i + 1];
	sort(zui, zui + n);

	for (int i = 1; i <= q; i++)
	{
		cin >> m;
		m += sumz[n];
		if (m < zui[0])
		{
			cout << sum[n] + tc << endl;
			continue;
		}
		int ha = upper_bound(zui, zui + n, m) - zui;
		ha -= 1;
		ha = n - ha;
		cout << sum[ha-1] + tc << endl;
	}
}

signed main()
{
    IOS;
	int tt = 1;
	while (tt--) solve();
	return 0;
}

思路2

题目误导这样算 其实不需要

前面算好了S_{min}=从小到大的忍耐度前缀和之和

假设每个人的不耐烦度的前缀和是sum[u]。由于要满足S_c \leq S_{min}+ M

化简得 \sum _{1}^{i-1}sum[u] + \sum _{i}^{n}sum[u] + (n-i+1) * t \leq \sum _{1}^{n}sum[u] + M

也就是选择插第i个人的队:

前i-1个人正常插队的时间+后面正常插队的时间+等待的时间tc * (n-i+1) ≤  S_{min} +M

很显然最后就是(n-i+1) * t _c\leq M 

这个 i 是二分答案的结果。

二分插队的时间 0 -> sum[n]   对mid时间对应起来是插第i个人的队 然后判断是否满足(n-i+1) * t _c\leq M

code2

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 1e5 + 2;
int n, m;
int t, a[N], q;
int solve()
{
    cin >> q;
    int l = 1, r = n+1;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if ((n - mid + 1) * t <= q) r = mid;
        else l = mid + 1;
    }
    if (l > n) return a[n] + t;
    return a[l - 1] + t;
}
signed main() {
    IOS;
    cin >> n >> m >> t;
    for (int i = 1; i <= n; i++) cin >> a[i];
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++) a[i] += a[i - 1];
    while (m--) cout << solve() << endl;
    return 0;
}

D.数组成鸡

题意

给你一个全是整数的数组,可以进行任意次+1 / -1 的操作

Q次询问 每次给一个integer M 问是否可以在任意次操作后使数组乘积等于给出的M(-1e9~+1e9)

思路

思路在于M很小 1e9 <= 2^30,所以满足它的情况并不多,可以预处理所有可能满足情况的M

最后只要判断M在不在预处理过的里面。

数组有n个数,以30为界,预处理每个数出现的次数存在map里

1. 如果 n <= 30

对数组a排序后 每个数减去最小值 得到一个暂时最优的排列

考虑最优的情况是 n = 2 此时满足乘积<M 就必须从1e4.5开始 所以从-1e5 ~ 1e5 正反枚举一次

也就是考虑反转

2. 如果n > 30

(1)判断每个数如果把他减到1 和另一个数减到-1之后的个数仍然大于30就没必要考虑了

(2)否则,就去枚举这么多数 把他们减去(x-1)这样 value = x 的数就减到1了 同理减到-1也跑一次,把可能的值放进去。

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
#define deb(x) cout << #x << " = " << x << '\n';
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
void solve()
{
	int n, m; cin >> n >> m;
	vector<int> a(n);
	map<int, int> cnt;
	set<int> ans;
	ans.insert(0);
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		cnt[a[i]] += 1;
	}
	if (n >= 30)
	{
		//一定要减少绝对值不等于1的数字个数。
		for (auto [x, y] : cnt)
		{
			if (n - cnt[x] - cnt[x - 2] > 30) continue;

			int mul = 1;
			bool flag = true;
			for (int i = 0; i < n; i++) {
				mul = mul * (a[i] - (x - 1));
				if (abs(mul) > 1e9) {
					flag = false;
					break;
				}
			}
			if (flag)
				ans.insert(mul);

			mul = 1, flag = true;
			for (int i = 0; i < n; i++) {
				mul = mul * (a[i] - (x + 1));
				if (abs(mul) > 1e9) {
					flag = false;
					break;
				}
			}
			if (flag) ans.insert(mul);
		}
	}
	else
	{
		sort(a.begin(), a.end());
		int tmp = a[0];
		for (int i = 0; i < n; i++) a[i] -= tmp;
		for (int i = -1e5; i <= 1e5; i++)
		{
			int mul = 1;
			bool flag = true;
			for (int j = 0; j < n; j++)
			{
				mul = mul * (a[j] + i);
				if (abs(mul) > 1e9)
				{
					flag = false;
					break;
				}
			}
			if (flag) ans.insert(mul);
		}
		for (int i = 0; i < n; i++) a[i] += tmp;
		reverse(a.begin(), a.end());
		tmp = a[0];
		for (int i = 0; i < n; i++) a[i] -= tmp;
		for (int i = -1e5; i <= 1e5; i++)
		{
			int mul = 1;
			bool flag = true;
			for (int j = 0; j < n; j++)
			{
				mul = mul * (a[j] + i);
				if (abs(mul) > 1e9)
				{
					flag = false;
					break;
				}
			}
			if (flag) ans.insert(mul);
		}
	}

	while (m--)
	{
		int x; cin >> x;
		if (ans.count(x)) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
}

signed main()
{
	IOS;
	int t = 1;
	while (t--) solve();
}

E.本题又主要考察了贪心

题意

n只鸡参加比赛 各个鸡当前的积分告诉你

接下来m场,第i场比赛的对阵双方是编号为ui​和vi​,积分规则是:胜方加三分,败方不得分,若战平则双方各得一分。请你计算在最好的情况下,我们的一号选手(炸鸡)能够排到第几名。

思路

因为n,m比较小-->dfs

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 110;
int n, m;

int minid = 0;
int a[N],l[N],r[N];
void dfs(int i)
{
	if(i > m) 
	{
		int now = 1;
		for(int i = 2;i <= n;i ++) if(a[i] > a[1]) now ++;
		minid = min(minid,now);
		return;
	}
	int u = l[i],v = r[i];
	a[u] += 3;
	dfs(i+1);
	a[u] -= 3;
	
	a[v] += 3;
	dfs(i+1);
	a[v] -= 3;
	
	a[u] ++,a[v] ++;
	dfs(i+1);
	a[u] --,a[v] --;
}

void solve()
{
    cin >> n >> m;
    minid = n;
    for(int i = 1;i <= n;i ++) cin >> a[i];
	for(int i = 1;i <= m;i ++) cin >> l[i] >> r[i];
	dfs(1);
	cout << minid << endl;
} 
signed main() 
{
	IOS;
	int tt = 1; cin >> tt;
	while(tt --) solve();
    return 0;
}

F.鸡数题!

题意

题目意思太麻烦了给链接

F-鸡数题!_2024牛客寒假算法基础集训营1 (nowcoder.com)

思路

第一个限制了是正数

第二个限制了严格单调递增

第三个限制了必须满足 n位全为1

第四个限制了每一位必须有0

其实应该推导出来的 但结论就是第二类斯特林数

斯特林数 - OI Wiki (oi-wiki.org) <---结论在这里

code

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
//#define mod 1000000007
using namespace std;
//uniform_int_distribution<int> u1(-99,99);
//uniform_int_distribution<int> u2(1,100);
//default_random_engine e;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int qmi(int a,int b)
{
	int res = 1;
	a = a % mod;
	while(b)
	{
		if(b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
int fac[N],inv[N];
void init()
{
	fac[0] = inv[0] = 1;;
	for(int i = 1;i < N;i ++)
	{
		fac[i] = fac[i-1] * i % mod;
		inv[i] = inv[i-1] * qmi(i,mod-2) % mod;
	}
}
void solve()
{
	int n,m; cin >> n >> m;
	int res = 0;
	for(int i = 0;i <= m;i ++)
	{
		int now = ((qmi(i,n) * inv[i] % mod) * inv[m-i] % mod) % mod;
		if((m-i)%2) res = ((res - (now % mod)) + mod) % mod;
		else res = (res + now % mod) % mod;
 	}
	cout << res << endl;
}

signed main()
{
	IOS;
	init();
	int tt = 1;
	while (tt--) solve();
	return 0;
}

G.why买外卖

题意

接下来要点炸鸡外卖

有若干个优惠,第i个优惠表示为“满ai元减bi元”,多个满减可以叠加

满减的具体结算流程:假设炸鸡原价x元,所有满足x≥ai的满减优惠可以一起同时被使用,优惠后价格为y元,只需要支付y元即可,y≤0则不用支付。

现在告诉你现在有m元,想知道炸鸡原价x最多为多少元

思路

大体是找到bi的前缀和的位置?想不起来了代码在下面 ---->

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
PII a[N], v[N];
int tmp[N];
void solve()
{
	int n, m; cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i].first >> a[i].second;
	sort(a + 1, a + 1 + n);
	int sum = 0;
	for (int i = 1; i <= n; i++)
	{
		sum += a[i].second;
		v[i].first = a[i].first - sum;
		v[i].second = sum;
	}
	sort(v + 1, v + 1 + n);
	for (int i = 1; i <= n; i++) tmp[i] = v[i].first;
	int idx = upper_bound(tmp + 1, tmp + 1 + n, m) - tmp;
	idx -= 1; // 第一个小于等于它的坐标
	if (idx < 1)
	{
		cout << m << endl;
		return;
	}
	for (int i = 1; i <= n; i++) swap(v[i].first, v[i].second);
	sort(v + 1, v + 1 + idx);
	cout << v[idx].first + m << endl;
}

signed main()
{
	//IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

H.01背包,但是bit

题意

一共n个物品,每个物品有重量vi,价值wi两个属性,你可以选择的重量m不能大于你选择的所有物品的异或和(按位或运算)的最大价值

思路

最重要的是需要以二进制的目光看

对于m的每一位为1的位置来说,都有2个选择

1.选它,然后这一位被固定死,然后看下一轮怎么选

2.不选它,那么之后的位置都可以选1

需要明白的是,如果每次都选最后的结果就是m,这个自己模拟一下循环就行

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
int w[N], v[N];
int n, k;
void solve()
{
    int n, m; cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> w[i] >> v[i];
    int pre = 0,res = 0;
    int now = 0;
    for (int i = 31; ~i; i--)
    {
        if ((m >> i) & 1)
        {
            now = pre + (1ll << i) - 1;
            pre += (1ll << i);
        }
        int sum = 0;
        for (int i = 1; i <= n; i++)
        {
            if ((now | v[i]) == now) sum += w[i];
        }
        res = max(res, sum);
    }
    int sum = 0;
    for (int i = 31; ~i; i--)
    {
        if ((m | v[i]) == m)sum += w[i];
    }
    res = max(res, sum);
    cout << res << endl;
}
signed main()
{
    IOS;
    int t = 1; cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

I.It's bertrand paradox. Again!

题意

题目太长点击链接->

I.It's bertrand paradox. Again!

思路

需要本地用随机生成1e5的数据模拟两个人的情况 找到它们的分布概率,通过找到它们分布的特征来判断是谁的决策,据说这叫机器学习))

这里的特征是x,y的距离,也可以是半径r的长度

code

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
uniform_int_distribution<int> u1(-99,99);
uniform_int_distribution<int> u2(1,100);
default_random_engine e;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 10010;
const int INF = 0x3f3f3f3f;

void test()
{
	int n = 1e5;
	double r1 = 0;
	for(int i = 1;i <= n;i ++)
	{
		int x = u1(e),y = u1(e);
		while(1)
		{
			int r = u2(e);
			if(x + r > 100 || x - r < -100 || y + r > 100 || y - r < -100) continue;
			else 
			{
				r1 += r;
				break;
			}
		}
	}
	double r2 = 0;
	for(int i = 1;i <= n;i ++)
	{
		while(1)
		{
			int x = u1(e),y = u1(e);
			int r = u2(e);
			if(x + r > 100 || x - r < -100 || y + r > 100 || y - r < -100) continue;
			else
			{
				r2 += r;
				break;
			}
		}
	}
	r1 /= n, r2 /= n;
	cout << r1 << ' ' << r2 << endl;
}

void solve()
{
	int n; cin >> n;
	double sum = 0;
	for(int i = 1;i <= n;i ++) 
	{
		int x,y,r; cin >> x >> y >> r;
		sum += r;
	}
	sum /= n;
	if((int)sum == 17) cout << "bit-noob" << endl;
	else cout << "buaa-noob" << endl;
}

signed main()
{
	IOS;
	e.seed(time(NULL));
	int tt = 1;
	while (tt--) solve();
	return 0;
}

J.又鸟之亦心

题意

在一个一维坐标系里有两个人,开始在x,y的位置

接下来给n个任务

要求x,y里面一直选一个人去做,然后要求全过程他们的距离最大值最小的方案,输出这个最大距离即可

思路

距离最大值的最小值问题用二分法,每次试探的mid指的是当前试探的最大值的最小值

用set维护,每个任务点都进去一次,意义是允许得到这样的mid中允许存在的点,如果不允许存在就erase那个点

因为它是有序的,对于下一个任务来说,set内的所有点到下个任务的距离都应该小于它

注意,这个set是不断更新的,只要保证set内一直有数据,就能保证这个最大距离mid是可以实现的,反之,一旦set空了就代表这样的距离达不到,也就是当前试探的mid太小了

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int w[N], v[N], a[N];
int n, k, x, y;

bool check(int mid)
{
	set<int> se;
	se.insert(x), se.insert(y);
	if (abs(x - y) > mid) return false;
	for (int i = 1; i <= n; i++)
	{
		while (!se.empty() && abs(*se.begin() - a[i]) > mid) se.erase(*se.begin());
		while (!se.empty() && abs(*se.rbegin() - a[i]) > mid) se.erase(*se.rbegin());
		if (se.empty()) return false;
		se.insert(a[i]);
	}
	return true;
}

void solve()
{
	cin >> n >> x >> y;
	for (int i = 1; i <= n; i++) cin >> a[i];
	int l = 0, r = 1e9;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	cout << l << endl;
}
signed main()
{
	IOS;
	int t = 1;
	while (t--) solve();
	return 0;
}

L.要有光

题意

涉及画图

L 要有光

思路

结论题

code

#include<iostream>
#define ine long long
using namespace std;
void solve()
{
    int c,d,h,w; cin >> c >> d >> h >> w;
    cout << 3 * c * w << endl;
}

signed main()
{
    int tt; cin >> tt;
    while(tt --) solve();
    return 0;
}

M.牛客老粉才知道的秘密

题意

蛮长的给链接---> M 牛客老粉才知道的秘密

思路

模拟一下就出来了        

code

#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1100;
const int INF = 0x3f3f3f3f;
int n, m, cnt;
int a[N];
bool st1[N], st2[N];
void solve()
{
	int n; cin >> n;
//     cout << n << ": ";
	if (n % 6 == 0)
	{
		cout << n / 6 << endl;
		return;
	}
// 	if (n < 6)
// 	{
// 		cout << 1 << endl;
// 		return;
// 	}
// 	if (n < 12)
// 	{
// 		cout << 2 << endl;
// 		return;
// 	}
// 	if (n > 12)
// 	{
		cout << n / 6 * 2 << endl;
// 		return;
// 	}
}

signed main()
{
	//IOS;
	int tt = 1; cin >> tt;
	while (tt--) solve();
	return 0;
}

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值