2023/02/16刷题
B. Pashmak and Flowers
链接
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
const int N = 200008;
int a[N];
signed main () {
int n;
int mmax = -99999999999;
int mmin = 999999999999;
scanf("%lld", &n);
for (int i = 0; i < n; i++) {
scanf("%lld", &a[i]);
if (a[i] > mmax) {
mmax = a[i];
}
if (a[i] < mmin) {
mmin = a[i];
}
}
//读入的同时直接求这个数组的最大最小值
int ans = 0;
if (mmin == mmax) {//如果最大和最小值相同的话
for (int i = n - 1; i >= 1; i--) {
ans = ans + i; //说明全部的数组都是都是一样的
}//直接打印n-1个满足条件
cout << 0 << ' ' << ans;
return 0;
}
sort(a, a + n);//然后排序
for (int i = 0; i < n; i++) {
int x = (mmax - mmin) + a[i];
int l = -1, r = n;
int mid;
while (l + 1 != r) {
mid = (l + r) / 2;
if (a[mid] < x) {
l = mid;
} else {
r = mid;
}
}//使用二分查找两次找到和a[i]配对的数的数量
int l2 = -1, r2 = n;
while (l2 + 1 != r2) {
mid = (l2 + r2) / 2;
if (a[mid] <= x) {
l2 = mid;
} else {
r2 = mid;
}
}
ans = ans + l2 - r + 1;//每次让加上求出的满足一次满足的数的数量
}
cout << mmax - mmin << ' ';//最后打印
cout << ans;//结果
return 0;
}
C. Perfect Team
链接
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
const int N = 100008;
void solve() {
int c, m, x;
cin >> c >> m >> x;
int cnt = c + m + x;//先求出全部的人数
int ans = 0;
int a = min(c, m);//求出c,m之中的最下值因为这两个必须要选择一个
ans = min(a, cnt / 3);//让a和cnt/3取最小值然后打印ans
// while (c > 0 && m > 0 && cnt >= 3) {
// c--;
// cnt = cnt - 3;
// m--;
//
// ans++;
//
//
//
// }
cout << ans << '\n';
}
signed main () {
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}
C. Poisoned Dagger
链接
一个二分答案题目,具体分析看代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
const int N = 100008;
int a[N];
void solve() {
int n, h;
scanf("%lld %lld", &n, &h);//h为boss的血量
for (int i = 0; i < n; i++) {
scanf("%lld", &a[i]);//读入攻击的时刻点
}
int l = 0, r = 1e18 + 1;
//h是小于等于1e8的
//所以在l到r区间之内肯定有满足条件的情况
while (l + 1 != r) {
int mid = (r + l) / 2;//对区间进行二分操作
int res = mid;//初始化为mid是因为最后的一个数肯定可以攻击mid个血量
//res用储存当前如果攻击的血量为mid的话,
for (int i = 0; i < n - 1; i++) {
res = res + min(a[i + 1] - a[i], mid);//然后取攻击时间的差值和mid进行比较取较小的那个
}
if (res < h) {//我们要寻找大于等于h的所以我们将分界线划分在<h的中间
//如果当前的mid小于h的话,分界线一定在右边所以我们将l更新为mid
l = mid;
} else {//否则将r更新为mid
r = mid;
}
}
cout << r << '\n';//打印r就是答案
}
signed main () {
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}