Codeforces Round # 693 (Div. 3) Problemlösungsbericht

Betreff: https://codeforces.com/contest/1472

A. Karten für Freunde

Thema

Ein Stück Papier hat eine Länge von w und eine Breite von h. Wenn w oder h eine gerade Zahl ist, kann es in zwei Papierhälften unterteilt werden. Wiederholen Sie dieselbe Aktion für die beiden Papierstücke und fragen Sie, ob ein Stück Papier vorhanden ist Papier kann in nicht weniger als n unterteilt werden

Ideen

Zerlegen Sie w und h getrennt und teilen Sie weiter durch 2, bis sie nicht mehr geteilt werden können, und teilen Sie sie in t1- und t2-Teile, sodass insgesamt t1 * t2-Teile vorhanden sind.

Hier können Sie durch Gewalt teilen oder Bitoperationen direkt verwenden, dh Lowbit (nehmen Sie die verbleibende Zahl von der Position der letzten 1 in der Binärdatei).

AC-Code

Gewalt

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
	int t; cin >> t;
	while(t --){
		int w, h, n;
		cin >> w >> h >> n;
		int t1 = 1, t2 = 1;
		while(w % 2 == 0) {
			t1 *= 2;
			w /= 2;
		}
		while(h % 2 == 0){
			t2 *= 2;
			h /= 2;
		}
		if(t1 * t2 >= n) puts("YES");
		else puts("NO");
	}
	return 0;
}

Lowbit

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & (-x)
int main(){
	int t; cin >> t;
	while(t --){
		int w, h, n;
		cin >> w >> h >> n;
		int t1 = lowbit(w), t2 = lowbit(h);
		if(t1 * t2 >= n) puts("YES");
		else puts("NO");
	}
	return 0;
}

B. Fair Division

Thema

Bei Zuckerstücken beträgt das Gewicht entweder 1 oder 2, fragen Sie, ob es in zwei Teile des gleichen Gewichts aufgeteilt werden kann

Ideen

Finden Sie die Nummer 1, t1, die Nummer 2, t2 und das Gesamtgewicht s.

Wenn s eine ungerade Zahl ist, wird es definitiv nicht funktionieren;

Wenn es in zwei Hälften geteilt ist, ist das jeder Person zugewiesene Gewicht eine ungerade Zahl, aber es gibt keine Süßigkeiten mit einem Gewicht von 1, die nicht funktionieren.

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
	int t; cin >> t;
	while(t --){
		int s = 0, n, t1 = 0, t2 = 0, x;
		cin >> n;
		while(n --){
			cin >> x;
			t1 += (x == 1);
			t2 += (x == 2);
			s += x;
		}
		if(s % 2){
			puts("NO");
			continue;
		}
		s /= 2;
		if(s % 2 && !t1) puts("No");
		else puts("YES"); 
	}
	return 0;
}

C. Weitsprünge

Thema

Die n Zahlen werden in der Anordnung a gespeichert, beginnend mit der i-ten Position, die mittlere Position tt wird auf i initialisiert, und dann kann die Entfernung von a [tt] jedes Mal übersprungen werden.

Wenn tt <= n, können Sie weiter springen, andernfalls endet das Spiel. Tmp ist die Summe der Gewichte des halben Sprunges. Fragen Sie nun, wie hoch der Maximalwert dieses tmp ist.

Ideen

Jede Position kann die ganze Zeit springen und aus n herausspringen. Wenn Sie beispielsweise von links nach rechts gehen, wenn 1 zu 6 springen kann und 3 zu 6 springen kann, dann ist 6 hier zweimal gesprungen, viele Wiederholungen Operation, aber wir können von hinten nach vorne gehen, so dass es gleichbedeutend mit Memoisierung sein kann, ein Sprung ist genug.

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn], dp[maxn]; // dp[i]就是从i位置开始跳出n需要加的权值
int main(){
	int t; cin >> t;
	while(t --){
		int n; scanf("%d",&n);
		for(int i = 1; i <= n; i ++){
			scanf("%lld", &a[i]);
		}
		for(int i = 1; i <= n; i ++) dp[i] = 0;
		ll ans = 0;
		for(int i = n; i >= 1; i --){
			ll d = i + a[i];
			dp[i] += a[i] + (d <= n ? dp[d] : 0);
			ans = max(ans, dp[i]);
		}
		cout << ans << endl;
	}
	return 0;
}

D. Gerade-ungerades Spiel

Thema

Zwei Personen wechseln sich ab, um n Steine ​​zu nehmen, bis sie fertig sind. Alice nimmt zuerst, Bob nimmt zweitens.

Wenn das Gewicht wi des von Alice genommenen Steins eine gerade Zahl ist, wird ihre Punktzahl wi addiert, andernfalls wird sie nicht addiert;

Wenn das Gewicht wi des von Bob genommenen Steins ungerade ist, wird seine Punktzahl wi addiert, andernfalls wird sie nicht addiert.

Fragen Sie, wer am Ende gewinnt oder unentschieden spielt.

Ideen

Wenn ich wählen möchte, muss ich jedes Mal den schwersten auswählen. Der beste Weg, um Punkte hinzuzufügen. Wenn ich keine Punkte hinzufügen kann, müssen Sie Punkte hinzugefügt haben. Nein, ich kann sie Ihnen nicht hinzufügen, nehmen Sie ihn .

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn];
int main(){
	int t; cin >> t;
	while(t --){
		int n, x; cin >> n;
		ll t1 = 0, t2 = 0;
		for(int i = 1; i <= n; i ++) {
			cin >> a[i];
		}
		sort(a + 1, a + n + 1, greater<int>()); //从大到小排序
		for(int i = 1; i <= n; i ++){
			if(i % 2 == 1 && a[i] % 2 == 0) t1 += a[i]; //Alice先手 偶数加分
			if(i % 2 == 0 && a[i] % 2 == 1) t2 += a[i]; //Bob后手 奇数加分
		}
		if(t1 > t2) puts("Alice");
		else if(t1 < t2) puts("Bob");
		else puts("Tie");
	}
	return 0;
}

E. Richtige Platzierung

Thema

N Kinder stellen sich auf, um Fotos zu machen, und jedes Kind hat Längen- und Breitenattribute wi, hi. Wenn ich vor j eingestuft werden soll, muss es wi <wj && hi <hj oder wi <hj && hi <wj erfüllen.

Fragen Sie nun nach jedem Kind i, geben Sie einen Index (willkürlich) des Kindes aus, der vor ihm angeordnet werden kann. Wenn es nicht existiert, geben Sie -1 aus

Ideen

Wenn festgelegt ist, dass wi der kleinere Wert unter (wi, hi) und hi der größere Wert unter (wi, hi) ist, muss zunächst nur geprüft werden, ob die Bedingung wi <wj && hi <hj erfüllt ist

Dann können Sie zuerst nach wi und dann nach hi sortieren, um sicherzustellen, dass w links kleiner oder gleich w rechts ist.

Die Idee der Doppelzeiger, i, j. i durchläuft das Array, j jagt, wenn a [j] .w <a [i] .w, dann aktualisiert tmp den Minimalwert von a [j] .h, id ist die Position des aktualisierten Minimalwerts, wenn tmp <a Im Fall von [i] .h kann das Kind in der ID-Position zu diesem Zeitpunkt vor dem Kind a [i] .id stehen.

AC-Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & (-x)
#define pp pair<int, int>
const int maxn = 2e5 + 10;
struct node{
	int x, y, id;
	bool operator < (const node &a) const{
		if(x != a.x) return x < a.x;
		return y < a.y;	
	}
}a[maxn];
int dp[maxn];
int main(){
	int t, n;
	cin >> t;
	while(t --){
		cin >> n;
		for(int i = 1; i <= n; i ++){
			cin >> a[i].x >> a[i].y;
			if(a[i].x > a[i].y) swap(a[i].x, a[i].y);
			a[i].id = i; dp[i] = -1;
		}
		sort(a + 1, a + n + 1);
		int tmp = 0x3f3f3f3f, id = -1, j = 1;
		for(int i = 1; i <= n; i ++){
			while(j < i && a[j].x < a[i].x){
				if(tmp > a[j].y){
					tmp = a[j].y;
					id = a[j].id;
				} j ++;
			}
			if(tmp < a[i].y) dp[a[i].id] = id;
		}
		for(int i = 1; i <= n; i ++){
			if(i > 1) cout << " ";
			cout << dp[i];
		}
		cout << endl;
	}
	return 0;
}

 

Ich denke du magst

Origin blog.csdn.net/weixin_43911947/article/details/112217993
Empfohlen
Rangfolge