codeforces round 748 题解 A~D2

文章目录

  • A. Elections
    • 题目大意
    • 思路
    • AC代码
  • B. Make it Divisible by 25
    • 题目大意
    • 思路
    • AC代码
  • C. Save More Mice
    • 题目大意
    • 思路
    • AC代码
  • D1. All are Same
    • 题目大意
    • 思路
    • AC代码
  • D2. Half of Same
    • 题目大意
    • 思路
    • AC代码

A. Elections

A. Elections

题目大意

有三个候选人,每个候选人都有一个初始票数,问每个候选人至少增加多少票才能绝对被选上。

思路

判断其中一个的初始票数是否大于另外两个的最大值,如果大于,那这个人就不需要增加选票,否则需要增加选票直至刚好超过最大值。

AC代码

A
#include
#include
using namespace std;

int main() {
	int t; cin >> t;
	while (t--) {
		int a, b, c; cin >> a >> b >> c;
		cout << (a > max(b, c) ? 0 : max(b, c) - a + 1)<<" ";
		cout << (b > max(a, c) ? 0 : max(a, c) - b + 1)<<" ";
		cout << (c > max(a, b) ? 0 : max(a, b) - c + 1) << endl;
	}
}

B. Make it Divisible by 25

B. Make it Divisible by 25

题目大意

给定一个数,每次可以删除一位,例如 3995删除第一位变成995,20065删除第一位变成65,显然去掉前导零。求最少多少次删除后,可以使得得到的数可以被25整除。

思路

我们不难发现,如果最后两位没办法整除25的话,那么最后的数,无论如何都不能整除25,也就是说,应该要先修改结尾的两位数,如果最后两位不对的话,前面修改再多都是没有用的。所以我们大可不必考虑前导零的问题,就只对最后两位进行删除就可以了,这个过程可以用bfs来实现。

当然这里也不是说只要最后两位可以整除25,那么整个数就可以整除25,不要混淆。

AC代码

#include
using namespace std;
typedef long long ll;
int bfs(ll n)
{
	queue<pair<ll,int>> q;
	q.push({n,0});
	map<ll,int> mp;
	while (!q.empty())
	{
        //记录数,记录步数
		pair<ll,int> p = q.front();
		q.pop();
		if (p.first<25)continue;
		if (p.first%25==0)return p.second;
		pair<ll,int> pge = {p.first/10,p.second+1};
		pair<ll,int> pshi = {p.first/100*10+p.first%10,p.second+1};
		if (!mp[pge.first])
		{
			mp[pge.first]=1;
			q.push(pge);
		}
		if (!mp[pshi.first])
		{
			mp[pshi.first]=1;
			q.push(pshi);
		}
	}
}
int main()
{
	int t;cin>>t;
	while (t--)
	{
		ll n;cin>>n;
		cout<<bfs(n)<<endl;
	}
}

C. Save More Mice

C. Save More Mice

题目大意

有一条长长的走廊,一只猫在走廊的起始点,有一堆老鼠在走廊的任意地方分布(不包括0,n位置),老鼠洞口在n处,老鼠进洞以后,就安全了,猫可以把它所在位置的老鼠全都吃掉。每次可以将一只老鼠向右移动一格,同时猫也会向右移动一格。求最终最多可以存活几只老鼠。

思路

简单贪心问题,老鼠一定是离洞口近的先跑,因为如果最远的先跑,那么最终的结局就是,猫离本来可以跑掉的老鼠越来越近,反而跑不掉了,所以能跑的一定先跑。

猫最远到达的位置是n-1,因为猫到洞口是不会吃老鼠的。

综上,就升序排序后反着枚举就ok

AC代码

#include
#include
using namespace std;
const int M = 4e5 + 100;
int a[M];
int main() {
	int t; cin >> t;
	while (t--) {
		int n, k;  cin>>n>>k;
		for (int i = 1; i <= k; i++) {
			cin >> a[i];
		}
		sort(a + 1, a + 1 + k);
		int ans = 0; int step = n - 1;
		for (int i = k; i >= 1; i--) {
			if (step - (n - a[i]) >= 0) {
				ans++; step -= n - a[i];
			}
			else
				break;
		}
		cout << ans << endl;
	}
	return 0;
}

D1. All are Same

D1. All are Same

题目大意

给定一个数组,可以对任意一个元素减k,求最大k为多少可以使得最终数组全部元素相同。

思路

因为是每次减,所以最后数组元素相同,所以最终元素一定是最小元素,所以就找出每个元素和最小元素的差值,然后求他们的最大公因数就欧克了。

AC代码

#include
#include
#include
using namespace std;
const int M = 45;
int a[M];
int cha[M];
inline int gcd(int a, int b) {
	int r;
	while (b > 0) {
		r = a % b;
		a = b;
		b = r;
	}
	return a;
}
int main() {
	int t; cin >> t;
	while (t--) {
		map<int, int> mp;
		int n; cin >> n; int minn = 1e9; int maxn = -1e9;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
			 minn = min(minn, a[i]);
			 maxn = max(maxn, a[i]);
		}
		int tot = 0;
		//cout << minn << endl;
		for (int i = 1; i <= n; i++) {
			if (a[i] != minn) {
				int ca = a[i] - minn;
				if (!mp.count(ca)) {
					mp[ca]++;
					cha[++tot] = ca;
				}
			}
		}
		int g = 0;
	//	for (int i = 1; i <= tot; i++) cout << cha[i] << " ";
		//cout << endl;
		for (int i = 1; i <= tot; i++) {
			g = gcd(g, cha[i]);
		}
		cout << g << endl;
	}
}

D2. Half of Same

D2. Half of Same

题目大意

给定一个数组,可以对任意一个数减k,求最大k为多少可以使得最终数组元素至少一半相同。

思路

这个题相较于D1复杂一些,但是思路大同小异,需要求出每个元素的差值与差值之间的最大购买后因数,然后枚举这些最大公因数,并判断有多少元素之间差值是枚举数的倍数,当元素差值数量大于n/2时就是一种情况,每次取max。

AC代码

#include
#include
#include
#include
using namespace std;
int a[50];
bool cmp(int a, int b) {
	return a > b;
}
int gcd(int a, int b) {
	return b == 0 ? a : gcd(b, a % b);
}
int main() {
	int t; cin >> t;
	while (t--) {
		map<int, int> mp;
		int n; cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
			mp[a[i]]++;
		}
		int f = 0;
		for (auto it : mp) {
			if (it.second >= n / 2) {
				cout << "-1" << endl;
				f = 1;
				break;
			}
		}
		if (f == 1)continue;
		set<int> s;
		for (int i = 1; i <= n; i++) {
			for (int j = i + 1; j <= n; j++) {
				int cha = abs(a[i] - a[j]);
				s.insert(cha);
			}
		}
		set<int> p;
		for (auto f1 : s) {
			for (auto f2 : s) {
				int g = gcd(f1, f2);
				p.insert(g);
			}
		}
		int ans = -1e9;
		for (auto tp : p) {
			if (!tp) continue;
			for (int i = 1; i <= n; i++) {
				int tmp = 0;
				for (int j = 1; j <= n; j++) {
					int cha = abs(a[i] - a[j]);
					if (cha % tp == 0) {
						++tmp;
					}
					if (tmp >= n / 2) ans = max(ans, tp);
				}
			}
		}
		cout << ans << endl;
	}
}

持续更新ing~

你可能感兴趣的:(算法,算法,c++)