B - Glider
这道题有点不明白,先放在这里以后看
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
LL dis[N], n, m, k, x, t, T, sum[N], h;
struct node
{
LL l, r;
} f[N];
int lbound(int x)
{
int L = x, R = n, ans = x;
while (L <= R)
{
int mid = (L + R) / 2;
if (sum[mid] - sum[x] < h)
{
ans = mid;
L = mid + 1;
}
else
R = mid - 1;
}
return ans;
}
int main()
{
cin >> n >> h;
for (int i = 0; i < n; i++)
{
cin >> f[i].l >> f[i].r;
if (i > 0)
{
dis[i] = f[i].l - f[i - 1].r;
sum[i] = sum[i - 1] + dis[i];
}
}
dis[n] = h + 1;
sum[n] = sum[n - 1] + dis[n];
LL ans = 0, tmp;
for (int i = 0; i < n; i++)
{
int pos = lbound(i);
tmp = (h - (sum[pos] - sum[i]) + f[pos].r) - f[i].l;
ans = max(ans, tmp);
}
cout << ans;
return 0;
}
C - Bacteria
思路:使用优先队列,取出x1、x2 如果x1==x2,就将2*x1放入优先队列中;如果不相等就将2*x1与x2放入队列,同时sum++。如果取出x1之后队列为空,说明只有一个细胞了,就可以break掉,如果sum的数量大于3e5,就可以认为没有答案输出“-1”;
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;
void ClearFloat()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
priority_queue<LL, vector<LL>, greater<LL>> q;
int main()
{
ClearFloat();
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> x;
q.push(x);
}
int sum = 0;
int flag = 0;
while (q.size())
{
LL x1 = q.top();
q.pop();
if (q.empty())
break;
LL x2 = q.top();
q.pop();
if (x1 == x2)
q.push(2 * x1);
else
{
sum++;
q.push(2 * x1);
q.push(x2);
}
if (sum > 3e5)
{
flag = 1;
break;
}
}
if (flag)
cout << "-1";
else
cout << sum;
return 0;
}
F - Tickets
思路: 预处理,先将0-1000000所有的unluckiness给算出来,然后直接输出答案即可
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;
int num[N];
string s;
void ClearFloat()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
int sum(int n)
{
int sum = 0;
while (n > 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
void pre()
{
for (int i = 0; i < 1000000; i++)
{
int a = sum(i / 1000);
int b = sum(i % 1000);
k = abs(a - b);
num[k]++;
for (int j = 0; j < k; j++)
{
v[i] += num[j];
//v[i]保存所有小于i的编号中不幸值更小的数量
}
}
}
int main()
{
ClearFloat();
pre();
cin >> T;
while (T--)
{
n = 0;
cin >> x;
cout << v[x] << endl;
}
return 0;
}
H - Theater Square
思路:英语看不懂不要紧,根据样例二能够看出这个tiles要横着铺,不能竖着铺。我们将整体分为三个部分,没有⛲️的行(上下都可能有),⛲️左边一块,⛲️右边一块,如果是奇数,说明就需要一块1×1的瓷砖,如果是偶数就不需要,然后求出三部分需要1×1的瓷砖数量总和。判断一下,如果是偶数就打破sum/2块瓷砖,如果是奇数需要多打破一块🧱
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;
void ClearFloat()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
int main()
{
ClearFloat();
int y, x1, x2, y1, y2;
cin >> x >> y;
cin >> x1 >> y1 >> x2 >> y2;
int sum = 0;
int a = 0, b = 0, c = 0;
a = y % 2 * (x - x2 + x1 - 1);//除去喷泉剩余行数需要打破几块🧱
b = (y1 - 1) % 2 * (x2 - x1 + 1);//喷泉左边需要打破几块🧱
c = (y - y2) % 2 * (x2 - x1 + 1);//喷泉右面需要打破几块🧱
// cout << a << " " << b << " " << c << endl;
sum = a + b + c;
if (sum % 2 == 0)
sum /= 2;
else
sum = (sum + 1) / 2;
cout << sum;
return 0;
}
I - Heist
思路:店铺拥有键盘的最小数量就是现存的最小编号到最大值编号之间的数量,最大编号➖最小编号➕1➖现存数量 就是被偷的最小数量
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
LL n, m, k, x, t, T;
void ClearFloat()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
int main()
{
ClearFloat();
LL minn = 9999999999, maxx = 0, ct = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> x;
minn = min(minn, x);
maxx = max(maxx, x);
}
cout << maxx - minn + 1 - n;
return 0;
}
J - Buying a TV Set
思路:求给出的比例的最小整数比,然后求min(最大长度/比例长度,最大宽度/比例宽度)就是答案
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
LL v[N], n, m, k, x, t, T;
void ClearFloat()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
int main()
{
ClearFloat();
LL a, b, sum = 0;
cin >> a >> b >> n >> m;
k = gcd(n, m);
// cout << k << endl;
n = n / k;
m = m / k;
// cout << n << " " << m << endl;
// cout << a / n << " " << b / m << endl;
sum = min(a / n, b / m);
cout << sum;
return 0;
}
K - Medians and Partition
思路:一开始我没看到 If the array has even length let median be smallest of of two middle elements. 这句话,看题解也没看明白是什么意思。这道题中位数的定义与数学里中位数的定义不同,如果是偶数个数字,中位数取中间呢个数的小的值,例如两个数「1,7」数学中的中位数是(1+7)/2=4、而在这道题中位数应该取1.
所以我们可以很轻易得出结论,一个小于m的数需要至少两个大于等于m的数组在一起才能使他们的中位数大于等于m,因此计算大于等于m的数的数量与小于m的数的数量差就是答案,注意如果小于m的数量更多的话答案应该是0,所以要和0取一个max.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define xx first
#define yy second
const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int v[N], n, m, k, x, t, T;
void ClearFloat()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
int main()
{
ClearFloat();
int l = 0, r = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> x;
if (x >= m)
r++;
else
l++;
}
cout << max(r - l, 0);
return 0;
}