Codeforces Round 920 (Div. 3)(A-E)

以下代码只给出solve()

A. Square

题目解释:随机给定一个正方形在坐标轴中的四个坐标,求面积。

题解:因为其正方形的边是平行于坐标轴的,直接求其边长即可。

代码:

void solve() {
	vector<ll>a(8);
	for (int i = 0;i < 8;i++) {
		cin >> a[i];
	}
	ll x = a[0] == a[2] ? abs(a[1] - a[3]) : abs(a[0] - a[2]);
	cout << x * x << endl;
}

B. Arranging Cats

题目解释:给两个字符串s,target,在给定的三种步骤下将s转化为target,求min的次数将s->target.

题解:给出了三种步骤,其中可以将s[i]=‘1’,s[j]=‘0’两个互换为s[i]=‘0’,s[j]=‘1’,毫无疑问这一步骤要最大化,运用尽可能多次,就是贪心思想,然后最后在考虑将其翻转为‘0’或‘1’。

我这里用了unordered_map这样的数据结构来存储s中‘1’的索引,在遍历过程中cnt记录target[i]=='1'并且i也不在mp中的个数,并将s[i]==target[i]==‘1’的i从mp中移除,最后min(cnt,mp.size())即为可以用最贪心的步骤的次数,abs(cnt-mp.size())即为不能用的次数。

代码:

void solve() {
	int n;
	cin >> n;
	string s, target;
	cin >> s;
	cin >> target;
	if (s == target) {
		cout << 0 << endl;
		return;
	}
	unordered_map<int,int>mp;
	for (int i = 0;i < n;i++) {
		auto c = s[i];
		if (c == '1')mp[i] = 1;
	}
	ll cnt = 0;
	for (int i = 0;i < n;i++) {
		if (target[i] == '1') {
			if (mp.count(i)) {
				mp.erase(i);
				continue;
			}
			else {
				cnt++;
			}
		}
	}
	ll ans = min(cnt, ll(mp.size()))+abs(cnt-ll(mp.size()));
	cout << ans << endl;
 
}

C. Sending Messages

题目解释:给定起始电量,每短时间所耗费的电量,开关机所耗费的电量,一个数组moments,必须在moments[i]时开机,问是否能打完所有电话

题解:也是贪心思想,总电量 - 从此时刻到下一打电话时刻所耗费的min电量,要么关机开机,要么什么也不做,看每一时刻f是否>0即可

void solve() {
	int n;
	ll a, b, f;
	cin >> n>>f>>a>>b;
	vector<ll>moments(n);
	for (int i = 0;i < n;i++) {
		cin >> moments[i];
	}
	f -= min(moments[0]*a, b);
	if (f <= 0) {
		cout << "NO\n";
		return;
	}
	for (int i = 1;i < n;i++) {
		f -= min(a*(moments[i]-moments[i-1]), b);
		if (f <= 0) {
			cout << "NO\n";
			return;
		}
	}
	cout << "YES\n";
}

D. Very Different Array

题目解释:给定两个数组a,b求其∑(i,n)=|ai−bi|的最大值

题解:将其排序,也是用贪心思想,要么是|a最大值-b最小值|或|a最小值-b最大值|,取其max即可

代码:

int n,m;
void solve() {
	cin >> n >> m;
	vector<ll>a(n), b(m);
	for (auto& x : a) {
		cin >> x;
	}
	for (auto& x : b) {
		cin >> x;
	}
	sort(a.begin(), a.end());
	sort(b.begin(), b.end());
	ll ans = 0;
	int l_a = 0, r_a = n - 1;
	int l_b = 0, r_b = m - 1;
	while (l_a<=r_a) {
		if (abs(a[l_a] - b[r_b]) >= abs(a[r_a] - b[l_b])) {
			ans += abs(a[l_a++] - b[r_b--]);
		}
		else {
			ans += abs(a[r_a--] - b[l_b++]);
		}
	}
	cout << ans << endl;
}

E. Eat the Chip

题目解释:Alice(A),Bob(B),在一棋盘上,A先动,每次只能向下、左下、右下移动,B与其相反。如果轮到A,并且A可以移动到B的位置,A赢,反之B赢。如果A移动到最下方,或B移动到最上方,平局(也就是轮到谁不能动了,就平局)。

题解:博弈问题,特殊情况,当A在B的同一行或下方时两人平局。

当两人竖向距离为偶数时,A可能赢,奇数时,B可能赢。

当A可能赢时,B要向远离A的横向距离移动,判断最后B移动到远离A的方向的尽头时,A是否能在两人错过之前到达,如果可以,那A就赢,否则平局。

当B可能赢时,我们只需要将B转化为先移动者,将A的位置预先处理下,然后按照上述方法处理即可。

void solve() {
	ll h, w, xa, ya, xb, yb;
	cin >> h >> w >> xa >> ya >> xb >> yb;
	if (xa >= xb) {
		cout << "Draw\n";
		return;
	}
	if ((xb-xa-1) % 2 == 0) {
		if (abs(ya - yb) <= 1) {
			cout << "Alice\n";
			return;
		}
		if (ya > yb) {
			//A:右,B:左
			if (ya - 1 <= (xb - xa + 1) / 2) {
				cout << "Alice\n";
				return;
			}
			else {
				cout << "Draw\n";
				return;
			}
		}
		else {
			if (w - ya <= (xb - xa + 1) / 2) {
				cout << "Alice\n";
				return;
			}
			else {
				cout << "Draw\n";
				return;
			}
		}
	}
	else {
		if (ya == yb) {
			cout << "Bob\n";
			return;
		}
		if (ya > yb) {
			ya = min(w, ya + 1);
			xa++;
		}
		else {
			ya = max(1ll, ya - 1);
			xa++;
		}
		if (ya < yb) {
			if (yb - 1 <= (xb - xa + 1) / 2) {
				cout << "Bob\n";
				return;
			}
			else {
				cout << "Draw\n";
				return;
			}
		}
		else {
			if (w - yb <= (xb - xa + 1) / 2) {
				cout << "Bob\n";
				return;
			}
			else {
				cout << "Draw\n";
				return;
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值