A
题意: 有两种食物,甜的与咸的,可以连续吃多次咸的,但是连续吃两次甜的食物就吃不下了,按照给出的顺序吃食物,问是否能吃完所有食物。
题解: 记录一下当前吃了几个甜的,如果已经吃了两次甜的,并且不是最后一份食物,那么就是 N o No No。
#include<bits/stdc++.h>
using namespace std;
#define fir first
#define sec second
#define endl "\n"
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;
void solve()
{
int n;
cin >> n;
int cnt = 0;
bool is_suc = true;
for(int i = 0; i < n; i ++)
{
string s;
cin >> s;
if(s == "sweet")
cnt ++;
else
cnt = 0;
if(cnt == 2 and i != n - 1)
is_suc = false;
}
if(is_suc)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
// cin >> t;
while(t --)
solve();
return 0;
}
B
题意: 有一个 n ∗ m n * m n∗m的迷宫, ′ . ′ '.' ′.′可以移动, ′ # ′ '\#' ′#′是墙壁。给出起点和移动方式,如果可以移动则移动,无法移动则呆在原地。
题解: 按照题意模拟就行了。
#include<bits/stdc++.h>
using namespace std;
#define fir first
#define sec second
#define endl "\n"
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;
void solve()
{
int n, m;
cin >> n >> m;
int x, y;
cin >> x >> y;
vector<string> g(n + 1);
for(int i = 1; i <= n; i ++)
cin >> g[i], g[i] = " " + g[i];
string str;
cin >> str;
for(auto t : str)
{
if(t == 'U' and x > 1 and g[x - 1][y] != '#')
x --;
else if(t == 'D' and x < n and g[x + 1][y] != '#')
x ++;
else if(t == 'L' and y > 1 and g[x][y - 1] != '#')
y --;
else if(t == 'R' and y < m and g[x][y + 1] != '#')
y ++;
}
cout << x << " " << y << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
// cin >> t;
while(t --)
solve();
return 0;
}
C
题意: 每份食物有甜度与咸度,你可以任意顺序吃食物,如果吃的甜度超过 X X X或者咸度超过 Y Y Y,就停止吃食物,最少吃多少份食物。
题解: 根据甜度和咸度分别排序,每次都吃尽可能大的。注意一下,可以正好等于 X , Y X,Y X,Y。
#include<bits/stdc++.h>
using namespace std;
#define fir first
#define sec second
#define endl "\n"
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;
void solve()
{
ll n, x, y;
cin >> n >> x >> y;
vector<int> a(n + 1), b(n + 1);
for(int i = 1; i <= n; i ++)
cin >> a[i];
for(int i = 1; i <= n; i ++)
cin >> b[i];
sort(a.begin() + 1, a.end(), greater<int>());
int cnt1 = 0;
for(int i = 1; i <= n; i ++)
{
cnt1 ++;
x -= a[i].fir;
if(x < 0)
break;
}
sort(b.begin() + 1, b.end(), greater<int>());
int cnt2 = 0;
for(int i = 1; i <= n; i ++)
{
cnt2 ++;
y -= a[i].sec;
if(y < 0)
break;
}
cout << min(cnt1, cnt2) << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
// cin >> t;
while(t --)
solve();
return 0;
}
D
题意: 一个长度 n n n的数组 a a a,和 q q q次提问。每次提问给出 b b b和 k k k。然后把这个 b b b和数组 a a a做一个计算。可以算出距离 d i d_i di。将所有的 d i d_i di排序(升序),求 d k d_k dk的值。
题解: 1 ≤ n , q ≤ 1 0 5 1 \leq n, q \leq 10^5 1≤n,q≤105,如果每次提问都真的计算一遍的话,时间复杂度会非常大,于是考虑二分答案。那么如果 a a a数组在 [ b − x , b + x ] [b - x, b + x] [b−x,b+x]之间的个数是大于 k k k,那么就需要缩小 x x x,否则增大 x x x,使得 a a a数组在区间 [ b − x , b + x ] [b - x, b + x] [b−x,b+x]中的个数恰好 k k k个。
顺便附上我常用的二分模板的出处,我觉得讲的比yxc讲得好,大家可以听一下:【二分查找为什么总是写错?】
#include<bits/stdc++.h>
using namespace std;
#define fir first
#define sec second
#define endl "\n"
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;
void solve()
{
int n, q;
cin >> n >> q;
vector<int> a(n + 1);
for(int i = 1; i <= n; i ++)
cin >> a[i];
sort(a.begin() + 1, a.end());
//二分的前提,数组有序
while(q --)
{
int b, k;
cin >> b >> k;
int l = -1, r = 1e9 + 1;
while(l + 1 != r) //二分模板,看一下视频理解
{
auto check = [&](int x)
{
int p1 = lower_bound(a.begin() + 1, a.end(), b - x) - a.begin();
//找出b - x的位置
int p2 = upper_bound(a.begin() + 1, a.end(), b + x) - a.begin();
//找出b + x的位置。
/*
lower_bound(起点,终点,数字) - 起点
lower_bound和upper_bound的用法很多,可以找出下标,可以直接找到数字。
python中应该也有对应的函数
lower_bound是在给出的范围内,找到第一个大于等于所求数字的数字。
upper_bound是在给出的范围内,找到第一个大于所求数字的数字。
*/
if(p2 - p1 + 1 > k)
return 1;
return 0;
};
int mid = l + r >> 1;
if(check(mid))
r = mid;
else
l = mid;
}
cout << r << endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
// cin >> t;
while(t --)
solve();
return 0;
}