2023/02/16刷题

B. Pashmak and Flowers

链接

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

链接

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

链接

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;
}
posted @ 2023-03-17 21:37  harper886  阅读(45)  评论(0)    收藏  举报