Ronda de Codeforces # 696

Ronda de Codeforces # 696

CF1474A Puzzle del futuro

Título:

En 2022, Mike descubrió dos enteros binarios ayb de longitud n (ambos solo están representados por números (y 1) con un 0 a la izquierda). Para no olvidarlos, quiso construir el entero d de la siguiente manera:

Agrega ayb bit a bit sin realizar una conversión de acarreo para obtener un entero c, por lo que c puede tener uno o más 2. Por ejemplo, el resultado de la suma bit a bit de 0110 y 1101 es 1211, y el resultado de la suma bit a bit de 011000 y 011000 es 022000;
después de eso, Mike dobla los números consecutivos iguales en c en 1 bit, obteniendo así d. Después de esta operación, 1211 se convierte en 121 y 022000 se convierte en 020 (por lo tanto, d no tendrá números consecutivos iguales).
Desafortunadamente, Mike perdió el entero a antes de calcular d él mismo. Ahora, para hacerlo feliz, debes encontrar un entero binario a de longitud n, haciendo d el entero más grande posible.

El entero más grande posible significa 102> 21, 012 <101, 021 = 21, etc.

responder:

Problema de la ley, solo encuentra la ley.
Encontramos que el primer lugar de a debe ser 1 (contando de izquierda a derecha). Para agrandar d, tenemos que agrandar ayb, y no puede haber el mismo número , entonces desde el segundo Al comienzo del bit, si el bit i-1 de ayb es igual al bit i-ésimo + 1 de b, significa que el bit ath no puede ser 1, sino que solo puede ser 0 , de lo contrario puede ser 1

Código:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
int main()
{
    
    
	int t;
	cin>>t;
	while(t--)
	{
    
    
		int n;
		cin>>n;
		string s;
		cin>>s;
		string b="1";
		for(int i=1;i<n;i++)
		{
    
    
			int w=s[i]-'0';
			int x,y;
			x=s[i-1]-'0';
			y=b[i-1]-'0';
			if(w+1==x+y)b+='0';
			else b+='1';
		}
		cout<<b<<endl;
	}
	return 0;
}

CF1474B Diferentes divisores

Título:

Encuentra un número que tenga al menos 4 divisores y la diferencia entre cada divisor sea al menos d.

responder:

De acuerdo con el significado de la pregunta, se pueden encontrar muchos ejemplos: el
primer dígito debe ser 1, el último dígito debe ser el producto de todos los números del medio, y luego el segundo dígito es mayor que el primero por d, y debemos asegurarnos de que a excepción del primer y último dígito Dígitos, los demás dígitos deben ser números primos, por lo que el último dígito es el más pequeño,
por lo que cada vez buscamos un número primo mayor que el dígito anterior + d

Código:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=1e7+9;
int tag[maxn],prime[maxn];
int cnt=0;
void Prime(int N)
{
    
    
	memset(tag,0,sizeof(tag));
	
	tag[0]=tag[1]=1;
	for(int i=2;i<N;i++)
	{
    
    
		if(!tag[i])
			prime[cnt++]=i;
		for(int j=0;j<cnt&&prime[j]*i<N;j++)
		{
    
    
			tag[i*prime[j]]=1;
			if(i%prime[j]==0)
				break;
		}
	}
}
int main()
{
    
    
	Prime(1000000);
	int t;
	cin>>t;
	while(t--)
	{
    
    
		int d;
		cin>>d;
		int x=1;
		x+=d;
		x=lower_bound(prime,prime+cnt,x)-prime;
		int y=prime[x];
		y+=d;
		y=lower_bound(prime,prime+cnt,y)-prime;
		cout<<prime[x]*prime[y]<<endl;
	}
}

Destrucción de matrices CF1474C

Título:

El título da una secuencia de números enteros positivos con una longitud de 2n. Ahora te pregunto si hay una x que te permita continuar realizando las siguientes operaciones hasta que la secuencia quede vacía:
Encuentra dos números a1, a2 de la secuencia , tal que a1 + a2 = = x, luego borre estos dos números de la secuencia, el valor de x también se actualiza, x = max (a1, a + 2).

responder:

Debido a que el rango de n no es grande, x se puede enumerar violentamente.
Dado que x aumenta monótonamente, la primera x debe ser el número más grande más otro número. El número más grande es seguro y el otro número se puede enumerar. Por ejemplo,
al principio, enumeramos 2n-1 otros números, y el número más grande juntos forman la x inicial, y luego en cada paso sabemos quién es x y quién es el valor máximo, entonces x-máximo se divide directamente en dos. Mire arriba. Continúe, si hay un número que no se puede encontrar en dos puntos, simplemente enumere otro número desde el principio y comience de nuevo
Complejidad: O (n 2 logn)
Esta pregunta depende principalmente de si está familiarizado con el conjunto.

Código:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2020;
int T, n, a[maxn], ans;
multiset<int> st;
vector<pair<int, int> > vec;

bool _check(int ii) {
    
    
    st.clear();
    for (int i = 0; i < 2*n-1; i ++) {
    
    
        if (i == ii) continue;
        st.insert(a[i]);
    }
    vec.clear();
    vec.push_back({
    
    a[2*n-1], a[ii]});
    ans = a[2*n-1] + a[ii];
    int tmp = a[2*n-1];
    for (int i = 1; i < n; i ++) {
    
    
        multiset<int>::iterator it = st.end(), it2;
        it --;
        int x = *it;
        st.erase(it);
        it2 = st.lower_bound(tmp - x);
        if (it2 == st.end()) return false;
        int y = *it2;
        if (x + y != tmp) return false;
        vec.push_back({
    
    x, y});
        tmp = max(x, y);
        st.erase(it2);
    }
    return true;
}

bool check() {
    
    
    for (int i = 0; i < 2*n-1; i ++) if (_check(i)) return true;
    return false;
}

int main() {
    
    
    scanf("%d", &T);
    while (T --) {
    
    
        scanf("%d", &n);
        for (int i = 0; i < 2*n; i ++) scanf("%d", a+i);
        sort(a, a+2*n);
        if (check()) {
    
    
            puts("YES");
            printf("%d\n", ans);
            for (auto x : vec) printf("%d %d\n", x.first, x.second);
        }
        else puts("NO");
    }
    return 0;
}

CF1474D Limpieza

Título:

Tome una piedra de dos posiciones adyacentes a la vez (puede tomar varias veces), y solo hay una oportunidad para intercambiar dos posiciones adyacentes, pregunte si puede quitar todas las piedras

responder:

Si el siguiente número es mayor que el anterior, veremos la situación donde el siguiente es 0 y el anterior no es 0 de adelante hacia atrás, por lo que debe ser imposible. De manera similar, eliminar de atrás hacia
adelante es la misma situación. Usamos pre para preprocesar la diferencia de adelante hacia atrás.
Suf preprocesa la diferencia de atrás hacia adelante .
Si las matrices pre y suf tienen la misma posición, significa que todo se puede quitar
porque hay una vez más. Oportunidad de intercambio, por lo que las dos posiciones i e i + 1 se intercambian directamente de forma violenta, y luego se calculan las nuevas presiones y sufrimientos de la posición actual para determinar si son iguales

Código:

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std ;
const int maxn = 2e5 + 10 ;
typedef long long ll ;
ll a[maxn] , pre[maxn] , suf[maxn] ;
const ll inf = 1e18 ;
 
int main(){
    
    
	int t ;
	cin >> t ;
	while(t--){
    
    
		ll n ;
		cin >> n ;
		memset(pre , 0 , sizeof(pre)) ;
		memset(suf , 0 , sizeof(suf)) ;
		for(ll i = 1 ; i <= n ; i++)	cin >> a[i] ;
		for(ll i = 1 ; i <= n ; i++)
		{
    
    
			if(a[i] >= pre[i-1])	pre[i] = a[i] - pre[i-1] ;
			else	pre[i] = inf / 2 ; // 预处理pre,当有不符合情况的时候,pre数组从此往后全为inf/2
		}
		
		for(ll i = n ; i >= 1 ; i--)
		{
    
    
			if(a[i] >= suf[i+1])	suf[i] = a[i] - suf[i+1] ;
			else	suf[i] = inf ;// 从后往前,如果有不符合,那么全为inf
		}
		
		bool flag = 1 ;
		for(ll i = 1 ; i <= n - 1 ; i++)
		{
    
    
			if(pre[i] == suf[i+1]){
    
     // 如果可以接上的话直接输出yes就行
				flag = 0 ;
				break ;
			}
			else
			{
    
    
				ll tmp1 = a[i] ; // 如果接不上,那么交换a[i]与a[i+1] 然后实现pre[i] 和 suf[i+1] 如果接的上输出yes
				ll tmp2 = a[i+1] ;
				if(tmp1 >= suf[i+2] && tmp2 >= pre[i-1])
				{
    
    
					tmp1 -= suf[i+2] ;
					tmp2 -= pre[i-1] ;
					if(tmp1 == tmp2)
					{
    
    
						flag = 0 ;
						break ;
					}
				}
			}
		}
		if(!flag)	cout << "YES" << endl ;
		else		cout << "NO" << endl ;
	}
	return 0 ;
} 

CF1474E ¿Qué es?

Título:

Para una permutación, puede elegir i, j (i ≠ j) para satisfacer a [j] = i, luego intercambiar a [i], a [j], y la ganancia de intercambio es (ij) 2 .
Permítale construir una permutación de longitud n para maximizar las ganancias del proceso de intercambio.

responder:

No es difícil encontrar que cada vez que intercambiamos, devolveremos al menos un número (es decir, un [i] = i). Cuando todas las posiciones regresen, no podremos intercambiar más, por lo que intercambiamos como máximo n-1 veces
y luego considere la distancia ¿Cuál es el logaritmo máximo de n-1? Solo hay un par, es decir (1, n), y nada más ¿Cuál es el
logaritmo máximo de n-2? Hay como máximo dos pares, a saber (1, n-1) y (2, n), (por supuesto, otras consideraciones son las mismas), y solo hay dos pares como máximo.
Cuando la distancia es n-3, hay solo dos pares,
entonces el beneficio máximo es (n -1) 2 + 2 * (n-2) 2 + 2 * (n-3) 2 +…
Entonces se calcula el beneficio.
En cuanto a los pasos, podemos considere lo que quiere, es decir, la matriz a está alojada al principio, y luego Obtenga (n-1) pares primero, luego (n-2) pares, para obtener el arreglo final y el proceso de intercambio

Código:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

typedef long long ll;

const int INF = 0x3f3f3f3f;
const int maxn = 2e5 + 7;
int a[maxn];
int main() {
    
    
    int T;scanf("%d",&T);
    while(T--) {
    
    
        int n;scanf("%d",&n);
        for(int i = 1;i <= n;i++) {
    
    
            a[i] = i;
        }
        vector<pair<int,int> >vec;
        ll ans = 0;
        int cnt = n - 1;
        for(int i = n - 1;;i--) {
    
     //交换两点的距离
            swap(a[i + 1],a[1]);
            vec.push_back({
    
    i + 1,1});
            ans += 1ll * i * i;
            cnt--;
            if(cnt == 0) break;
            if(i == n - 1) continue;
            
            swap(a[n - i],a[n]);
            vec.push_back({
    
    n - i,n});
            ans += 1ll * i * i;
            cnt--;
            if(cnt == 0) break;
        }
        printf("%lld\n",ans);
        for(int i = 1;i <= n;i++) {
    
    
            printf("%d ",a[i]);
        }
        printf("\n");
        printf("%d\n",n - 1);
        for(int i = vec.size() - 1;i >= 0;i--) {
    
    
            printf("%d %d\n",vec[i].first,vec[i].second);
        }
    }
    return 0;
}


CF1474F 1 2 3 4…

Título:

responder:

Código:

Supongo que te gusta

Origin blog.csdn.net/qq_35975367/article/details/114271429
Recomendado
Clasificación