贪心,判断一下左边和右边
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#pragma GCC optimize(2)
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define one first
#define two second
using namespace std;
typedef long long ll;
typedef pair<int, int > PII;
const int N = 1e6 + 5, mod = 1e9 + 9, INF = 0x3f3f3f3f;
int t, n, x, a, b;
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// cin.tie(0);
// cout.tie(0);
// ios::sync_with_stdio(0);
cin >> t;
while (t--) {
cin >> n >> x >> a >> b;
if (abs(a - b) == n - 1) {
cout << n - 1 << endl;
continue;
}
int sum = a + b;
b = a + b - min(a, b);
a = sum - b;
int tmp1 = a - 1, tmp2 = n - b;
b = b + min(x, tmp1 + tmp2);
cout << (b - a) << endl;
}
}
因为当x大于等于y的时候是一定可以通过把x减一的方式将他变成y的,所以我们要尽可能把x变大。策略就是如果x是奇数就把他减去1变成偶数,偶数就直接成二分之三。特判一下如果x是奇数并且(x - 1) * 3 / 2 等于x的话就不可能达到
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#pragma GCC optimize(2)
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define one first
#define two second
using namespace std;
typedef long long ll;
typedef pair<int, int > PII;
const int N = 1e6 + 5, mod = 1e9 + 9, INF = 0x3f3f3f3f;
ll t, x, y;
int main()
{
cin >> t;
while (t--) {
cin >> x >> y;
while (1) {
if (x >= y) {
puts("YES");
break;
}
if (!(x & 1)) {
x = x * 3 / 2;
} else {
x--;
ll tmp = x * 3 / 2;
if (tmp == x + 1 || tmp == 0) {
puts("NO");
break;
}
}
}
}
}
/*
1
858993461 1000000000
*/
在读入的时候一边读一边用map记录并更新当前这个数上次出现的位置,更新答案。
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#pragma GCC optimize(2)
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define one first
#define two second
using namespace std;
typedef long long ll;
typedef pair<int, int > PII;
const int N = 2e5 + 5, mod = 1e9 + 9, INF = 0x3f3f3f3f;
int t, n;
int a[N];
map <int, int> Map;
int main()
{
cin >> t;
while (t--) {
cin >> n;
Map.clear();
int ans = INF;
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
if (Map[a[i]] != 0) {
if (i - Map[a[i]] + 1 < ans) {
ans = i - Map[a[i]] + 1;
Map[a[i]] = 0;
}
}
Map[a[i]] = i;
}
if (n == 1) {
puts("-1");
continue;
}
if (ans != INF)
cout << ans << endl;
else
puts("-1");
}
}
D - Yet Another Monster Killing Problem
特判后把奥特曼二分着来打怪兽
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#pragma GCC optimize(2)
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define one first
#define two second
using namespace std;
typedef long long ll;
typedef pair<int, int > PII;
const int N = 2e5 + 5, mod = 1e9 + 9, INF = 0x3f3f3f3f;
int t, n, m, maxx, tid, pos, res;
int a[N], id[N];
PII e[N];
int main()
{
cin >> t;
while (t--) {
cin >> n;
int w = -1;
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
w = max(w, a[i]);
}
cin >> m;
bool flag = 1;
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &e[i].first, &e[i].second);
if (e[i].first >= w)
flag = 0;
}
if (flag) {
puts("-1");
continue;
}
sort(e + 1, e + 1 + m);
maxx = 0;
for (int i = m; i >= 1; --i) {
if (e[i].second > maxx) {
maxx = e[i].second;
tid = i;
}
id[i] = tid;
}
pos = 1, res = 0;
while (pos <= n) {
tid = lower_bound(e + 1, e + 1 + m, PII(a[pos], -1)) - e;
tid = id[tid];
maxx = e[tid].second;
for (int j = 1; j <= maxx; ++j) {
if (a[pos] <= e[tid].first) pos++;
else {
tid = lower_bound(e + 1, e + 1 + m, PII(a[pos], -1)) - e;
tid = id[tid];
if (e[tid].second >= j) {
maxx = e[tid].second;
pos++;
}
else
break;
}
}
res++;
}
cout << res << endl;
}
}
/*
1
5
78 22 90 12 42
5
51 1
87 3
48 2
13 1
98 5
*/
本文解析了四道编程挑战题目,包括两学生竞争、魔法棒、受支配子数组及另一怪物击杀问题。通过贪心策略、二分查找等算法解决实际问题,深入探讨了数据结构和算法的应用。
308

被折叠的 条评论
为什么被折叠?



