2021-01-13 solución de problemas de formación

concurso

一. A. Phoenix y el equilibrio

1. Al efecto:

Hay n números, de 2 a 2 ^ n. Divídalos al azar en 2 pilas (cada pila es n / 2) y asegúrese de que n sea un número par, de modo que la diferencia entre la suma de las dos pilas de n / 2 números es el más pequeño

2. Solución de problemas:

Buscando la regla, encontré que está dividida en una pila: 2 n / 2 , 2 n / 2 + 1 , ..., 2 n-1 , (números totales n / 2), y la
otra pila es · : 2 1 , 2 2 , ... 2 n / 2-1 , 2 n , en
este caso, la diferencia entre los dos lados es la más pequeña. La
fórmula es: 2 n / 2 + 1 -2
usa pow para cumplir T, y usa potencia rápida

Después de leer los métodos de otras personas, descubrí que también puede ser el número anterior * 2 + 2, la esencia es casi la misma

3.ac código:

#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
//long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
typedef long long ll;
ll quick_pow(ll a,ll b) {
    
    
    ll ans = 1;
    while(b) {
    
    
        if(b&1)
            ans *= a;
        a *= a;
        b >>= 1;
    }
    return ans;
}
int main(){
    
    
	int t;
	int n,i;
	long long int a[40];
	for(i=2;i<=32;i+=2){
    
    
		a[i]=quick_pow(2,i/2+1)-2;
	}
	while(cin>>t){
    
    
		while(t--){
    
    
			cin>>n;
			cout<<a[n]<<endl;
		}
	}
 
}

二. G. Selección impar

1. Al efecto:

Hay una matriz de n números. Ahora elija x números de los n números y deje que su suma sea un número impar. Si es así, sí, no no

2. Solución de problemas:

Primero, excluya algunos casos especiales que definitivamente no son posibles:
1. Todos pares
2. Todos impares, pero x es un número par
3. Cuando n == x, el
caso restante donde la suma es par / impar es par , el se garantiza que el problema sea x <n, siempre puede encontrar un número par primero, ajustar el número impar de acuerdo con el número par y hacer que el resultado final sea un número impar

3.ac código:

#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
//long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
typedef long long ll;

int main(){
    
    
	int n;
	int t;
	int x;
	int odd,even;
	int a[1001];
	while(cin>>t){
    
    
		while(t--){
    
    
			odd=0;
			even=0;
			cin>>n>>x;
			for(int i=0;i<n;i++){
    
    
				cin>>a[i];
				if(a[i]%2==0)
				even++;
				else
				odd++;
			}
			if(n==even)
			printf("No\n");
			else if(n==odd && x%2==0)
			printf("No\n");
			else if(n==x&&odd%2==0)
			printf("No\n");
			else
			printf("Yes\n");
			
		}
	}
 
}

三. H. Odio subsecuente

1. Al efecto:

Ahora solo hay 0/1 en la cadena s. Si la subsecuencia de la cadena tiene "010" / "101", la cadena no es buena. Ahora puede ajustar el número de ciertas posiciones en la cadena y establecer 0- > 1 / 1-> 0, para que esta cadena sea buena, pregunte al menos cuántos cambiar, puede cambiarlos todos

2. Solución de problemas:

Obviamente, debe realizarse al final. Todos los 1 a la izquierda y todos los 0 a la derecha, o todos los 0 a la izquierda y todos los 1 a la derecha, se
consideran dp. Dos dp, uno registra el número que debe ser cambiado en la i-ésima posición con 1 a la izquierda y 0 a la derecha, y los otros registros En otro caso, encuentre el más pequeño y
use sum0 para registrar todos los 0, sum1 registre todos los 1.
x0 registra la posición que es el anterior 0, x1 es. . 1,
cuando la izquierda y la derecha 1 0, es apropiado para cambiar: x0 + sum1-x1
si izquierda 1 y derecha 0, es apropiado para cambiar: x1 + sum0-x0
encuentra el mínimo

3.ac código:

#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
//long long int dp2[400000],dp1[400000],a[400000];
using namespace std;
typedef long long ll;

int main(){
    
    
	int t,n,i,j;
	char s[2000];
	while(cin>>t){
    
    
		while(t--){
    
    
			scanf("%s",s);
			n=strlen(s);
			int sum0=0,sum1=0;
			int x0=0,x1=0;
			for(i=0;i<n;i++){
    
    
				if(s[i]=='0')
				sum0++;
				else
				sum1++;
			}
			int out=2000;
			for(i=0;i<n;i++){
    
    
				if(s[i]=='0')
				 x0++;
				else
				 x1++;
				out=min(out,min(x1+sum0-x0,x0+sum1-x1));
			}
			cout<<out<<endl;
		}
	}
 
}

四. B. Phoenix y la belleza

1. Al efecto:

Dados n números, puede agregar cualquier número a cualquier posición en él para hacer que la suma de m números consecutivos en la matriz sea la misma. Si es posible, genere el número de números de matriz y el número en la matriz, si no, la salida -1

2. Solución de problemas:

Cuando hay más de m números diferentes entre n números, no es posible. Suponiendo que m = 3, la matriz es a, b, c, d, a, b, c, d, ¡habrá a + b + c! = b + c + d
Cuando hay m tipos de n números, copie m números n veces.
Cuando n números sean menores que m tipos, sume m tipos y repita m tipos n veces

3.ac código:

#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#define N 300010
using namespace std;
typedef long long ll;
int a[N],b[N];
set<int> s;
	
int main(){
    
    
	int t,n,k;
	int i,j;

	while(cin>>t){
    
    
		while(t--){
    
    
			s.clear();
			cin>>n>>k;
			memset(b,0,sizeof(b));
			memset(a,0,sizeof(a));
			for(i=0;i<n;i++){
    
    
				cin>>a[i];
				s.insert(a[i]);
			}
			int n1=s.size();
			if(n1>k){
    
    
				printf("-1\n");
				continue;
			}
			j=1;
			while(s.size()<k){
    
    
				s.insert(j);
				j++;
			}
			set<int>::iterator iter;
			int x=0;
			for(iter=s.begin();iter!=s.end();iter++){
    
    
				b[x++]=*iter;
			}
			printf("%d\n",n*x);
			for(i=0;i<n-1;i++){
    
    
				for(j=0;j<x;j++){
    
    
					printf("%d ",b[j]);
				}
			}
			for(j=0;j<x-1;j++){
    
    
				printf("%d ",b[j]);
			}
			printf("%d\n",b[j]);
		}
	}
} 

五. I. Juego en hojas

1. Al efecto:

Dado un árbol sin raíz con n nodos, dos personas se turnan para tomar, cada vez que pueden tomar el nodo hoja y eliminar el borde conectado a él, quien obtenga x, quien gane

2. Solución de problemas:

En el juego, todos elegirán el mejor.
Nota: Si x es un nodo hoja al principio, e incluso el árbol tiene solo un nodo, la primera mano gana
el borde conectado ax en el caso restante> = 2, y ambos tienen la mejor solución En este caso, eventualmente se convertirá en la siguiente imagen.
Inserte la descripción de la imagen aquí
En este momento, el primer movimiento será derrotado.
Dado que ninguno de ellos quiere terminar el subárbol, de lo contrario x se convertirá en una hoja, por lo que las dos personas definitivamente dejarán dos subárboles y convertirán x en una hoja hasta que no haya otra forma de obtenerla. Así que este es el caso anterior.

Entonces podemos juzgar quién gana solo juzgando la paridad de n

3.ac código:

#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#define N 300010
using namespace std;
typedef long long ll;
int a[N],b[N];
int main(){
    
    
	int t;
	int x,n;
	int u,v;
	int i;
	while(cin>>t){
    
    
		while(t--){
    
    
			memset(a,0,sizeof(a));
			cin>>n>>x;
			for(i=0;i<n-1;i++){
    
    
				cin>>u>>v;
				a[u]++;
				a[v]++;
			}
			if(a[x]<=1||n%2==0){
    
    
				printf("Ayush\n");
			}else{
    
    
				printf("Ashish\n");
			}
		}
	}

} 

六. C. Phoenix y distribución

1. Al efecto:

Da una cadena de longitud n, divídela en k partes y ajusta el orden para que la subsecuencia con el
orden lexicográfico más grande sea ​​la más pequeña. El tamaño lexicográfico: a <b, ab <abb, abc <ac ...
Esta pregunta significa, esto debe haber una de las k subcadenas con el orden lexicográfico más grande, de modo que el orden lexicográfico más grande sea lo más pequeño posible

2. Solución de problemas:

Referencia
Primero ordene la cadena y divídala de acuerdo
con esto. Si desea la más grande y la más pequeña, debe ser una combinación de la primera k y la última nk. El orden del diccionario será lo más pequeño posible para
determinar si la primera k Las letras son iguales. Si son diferentes, entonces la primera La cadena donde se encuentra s [k] debe ser la más grande lexicográficamente. La forma de hacerla más pequeña es que la cadena solo tenga s [k], y el resto nk los caracteres se asignan a las letras menores que s [k], como abbb | cccc, divididos en accc, b, b, b.
Si los anteriores son iguales, juzgue si los siguientes nk caracteres son iguales.
Si son lo mismo, como aaa | bbbb, los últimos nk caracteres se distribuirán uniformemente.
Si hay diferencias, como aaa | bbc, entonces este último se asigna a una a, porque nk diferentes deben ser grandes y pequeños. están separados, el grande en la parte posterior correrá hacia el frente y se hará más grande. Poniéndolos en orden lexicográfico será el más pequeño. Como ac> abbc

3.ac código:

#include<stdio.h>
#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#define N 300010
using namespace std;
typedef long long ll;
char s[N];
int main(){
    
    
	int t;
	int n,k;
	int i;
	while(cin>>t){
    
    
		while(t--){
    
    
			cin>>n>>k;
			scanf("%s",s);
			sort(s,s+n);
			int flag=0;
			for(i=1;i<k;i++){
    
    
				if(s[i]!=s[i-1])
				flag=-1;
			}
			if(flag==-1){
    
    
				printf("%c\n",s[k-1]);
			}else{
    
    
				for(i=k+1;i<n;i++){
    
    
					if(s[i]!=s[i-1])
					flag=-1;
				}
				if(flag==-1){
    
    
					printf("%c",s[k-1]);
				   for(i=k;i<n;i++){
    
    
					printf("%c",s[i]);
				    }
				    printf("\n");
				}else{
    
    
					int x=(n-k)/k;
					printf("%c",s[k-1]);
					for(i=k;i<k+x;i++){
    
    
						printf("%c",s[i]);
					}
					if((n-k)%k!=0)
					printf("%c",s[k]);
					printf("\n");
				}
				
			}
		}
	}
	


} 

七. D. Phoenix y la ciencia

1. Al efecto:

2. Solución de problemas:

3.ac código:

Supongo que te gusta

Origin blog.csdn.net/weixin_46064382/article/details/112703786
Recomendado
Clasificación