Informe de resolución de problemas de Codeforces Round # 693 (Div.3)

Enlace de asunto: https://codeforces.com/contest/1472

A. Tarjetas para amigos

Tema

Una hoja de papel tiene w de largo y h de ancho. Si w o h es un número par, entonces se puede dividir en dos mitades de papel. Repita la misma acción para las dos hojas de papel y pregunte si una el papel se puede dividir en no menos de n

Ideas

Descomponga wyh por separado y siga dividiendo por 2 hasta que no se puedan dividir, y divídalos en partes t1 y t2, por lo que hay partes t1 * t2 en total.

Aquí puede dividir por la fuerza, o puede usar operaciones de bit directamente, es decir, lowbit (tome el número restante de la posición del último 1 en el binario).

Código AC

violencia

#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. División justa

Tema

n trozos de azúcar, el peso es 1 o 2, pregunte si se puede dividir en dos partes del mismo peso

Ideas

Encuentre el número de 1, t1, el número de 2, t2 y el peso total s.

Si s es un número impar, definitivamente no funcionará;

Si se divide en dos mitades, el peso asignado a cada persona es un número impar, pero no hay caramelos con un peso de 1, eso no funcionará.

Código AC

#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. Saltos largos

Tema

Los n números se almacenan en la matriz a, comenzando desde la i-ésima posición, la posición media tt se inicializa en i, y luego la distancia de a [tt] se puede saltar cada vez.

Si tt <= n, entonces puede continuar saltando; de lo contrario, el juego termina, tmp es la suma de los pesos del salto medio, y ahora pregunte cuál es el valor máximo de este tmp.

Ideas

Cada posición puede saltar todo el tiempo, saltando de n. Si recorre de izquierda a derecha, por ejemplo, si 1 puede saltar a 6 y 3 puede saltar a 6, entonces 6 aquí ha saltado dos veces, muchas repeticiones de la Operación, pero podemos atravesar de atrás hacia adelante, por lo que puede ser equivalente a memorizar, un salto es suficiente.

Código AC

#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. Juego par-impar

Tema

Dos personas se turnan para tomar n piedras hasta terminar. Alice ocupa el primer lugar, Bob ocupa el segundo.

Si el peso wi de la piedra tomada por Alice es un número par, entonces su puntuación se agregará wi; de lo contrario, no se agregará;

Si el peso wi de la piedra tomada por Bob es impar, entonces su puntaje se agregará wi, de lo contrario no se agregará.

Pregunte quién gana o empata al final.

Ideas

Si quiero elegir, debo elegir el más pesado cada vez. La mejor manera de sumar puntos. Si no puedo sumar puntos, entonces debes haber agregado puntos. No, no puedo agregarlos a ti, llévalo .

Código AC

#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. Colocación correcta

Tema

N niños se alinean para tomar fotografías, y cada niño tiene atributos de largo y ancho wi, hi. Si i va a ser clasificado antes de j, debe satisfacer wi <wj && hi <hj o wi <hj && hi <wj.

Ahora pregunte por cada niño i, genere un subíndice (arbitrario) del niño que se pueda arreglar frente a él, si no existe, salida -1

Ideas

En primer lugar, si se estipula que wi es el valor más pequeño entre (wi, hi) y hi es el valor más grande entre (wi, hi), solo es necesario ver si se cumple la condición wi <wj && hi <hj

Luego, puede ordenar primero por wi y luego por hola para asegurarse de que w de la izquierda sea menor o igual que w de la derecha;

La idea de dobles punteros, i, j. i atraviesa la matriz, j persigue, si a [j] .w <a [i] .w entonces tmp actualiza el valor mínimo de a [j] .h, id es la posición del valor mínimo actualizado, si tmp <a En el caso de [i] .h, entonces el niño en la posición de identificación puede pararse frente al niño a [i] .id en este momento.

Código AC

#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;
}

 

Supongo que te gusta

Origin blog.csdn.net/weixin_43911947/article/details/112217993
Recomendado
Clasificación