codeforces # 634 (div3) solución AE

A. caramelos y dos hermanas
  • Divide el dulce en dos partes, a y b, y a <b, a + b = n

  • Según el análisis de la condición en la pregunta, el número de dulces n <= 2 no tiene solución

  • n es un número par res = n / 2-1; número impar res = n / 2

  • res = (n - 1) / 2

	cin >> t;
	while(t--){
		cin >> n;
   		cout << (n - 1) / 2;
    }
B. Construir la cadena
  • Construya una subcadena de longitud n y satisfaga todas las subcadenas de longitud a con solo b letras diferentes
  • Primero emite la cadena b con letras diferentes b, la cadena n es n // b veces la cadena b
	cin >> t;
	while(t--){
		cin >> n >> a >> b;
		for(int i = 0; i < n; i++) cout << char('a' + i % b);  
		cout << endl;
	}
C. Dos equipos componiendo
  • Hay un grupo de estudiantes, y cada estudiante tiene una sola habilidad. Ahora los estudiantes están divididos en dos grupos de números iguales. Los estudiantes en un grupo solo tienen las mismas habilidades, y los estudiantes en el otro grupo solo tienen habilidades diferentes. Número máximo de personas.

  • El resultado máximo posible es la mitad del número total.

  • Use el conjunto de libros para registrar la cantidad de personas que usan las habilidades i, y idx para registrar la cantidad de habilidades

  • Encuentre el número de personas que usan la misma habilidad mx más, el resultado es <= mx

  • Discuta por situación 1. n == 1, n == idx se prefiere una situación especial 2. Cuando mx e idx son iguales, hay una intersección de elementos res = mx-1;

Cuando mx e idx no son iguales, res = min (mx, idx);

#define endl '\-n'
using namespace std;
const int kN = 2 * 1e5 + 5;
int t,n,x,idx,arr[kN],mx,res;
//int book[kN];//map要比直接开数组快,但更耗内存
map<int,int> book;
int main(void){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin >> t;
	while(t--){
		idx = mx = 0;
		book.clear();
		cin >> n;
		//memset(book,0,sizeof(book));
		for(int i = 0; i < n; i++){
			cin >> x;
			if(!book[x]) book[x] = 1,arr[idx++] = x;
			else ++book[x]; 
		}
		//idx 不同技能数 寻找最大相同技能数
		for(int i = 0; i < idx; i++){
			if(book[arr[i]] > mx) mx = book[arr[i]];
		} 
		if(mx == idx) cout << mx - 1 << endl;//存在一个元素的交集
        else cout << (mx > idx ? idx : mx)<< endl;
	}
	return 0;
}
D. Anti-Sudoku
  • Cada conjunto de muestras de prueba es una matriz de 9x9
  • La salida se encuentra con cada fila, cada columna tiene dos números idénticos
  • En cada fila, el valor promedio de cada columna aparece solo una vez, reemplaza todos de 2 a 1 ... etc.
	cin >> t;
	while(t--){
		for(int i = 0; i < 9; i++){
			cin >> s;
			for(auto x : s){
				if(x == '2') cout << '1';
				else cout << x;
			}
			cout << endl;
		}
	}
E1 Palindrome de tres bloques (versión fácil)
  • palindrome de tres bloques (a, a, ..., a, b, b, ..., b, a, a, ..., a) El número de a y b puede ser 0, el número de a antes y después es igual a x, b
  • Ingrese una secuencia para encontrar la subsecuencia legal más larga, que puede ser discontinua en la secuencia
  • pre (i, j) es el número de j en los primeros números i
  • Violencia: enumerar a, b
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#define endl '\n'
using namespace std;
const int kN = 2010, kM = 30;
int t,n,ans,a[kN],pre[kN][kM];
int main(void){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin >> t;
	while(t--){
		ans = 0;
		cin >> n;
		for(int i = 1; i <= n; i++) cin >> a[i];
		for(int i = 1; i <= n; i++){//前缀和... 
			for(int j = 1; j <= 26; j++) pre[i][j] = pre[i - 1][j] + (a[i] == j);
		}
		for(int l = 1; l <= n; l++){//x从0开始枚举 
			for(int r = l; r <= n; r++){//枚举r 
				int x = 0, y = 0;
				for(int k = 1; k <= 26; k++){//l ~ r 中间范围 
					x = max(x,min(pre[l - 1][k],pre[n][k] - pre[r][k]));//左右两端k的个数可以为0 
					y = max(y,pre[r][k] - pre[l - 1][k]);//中间k的个数,可以为0	
				}
				ans = max(ans, x * 2 + y);//维护最大子序列长度 
			}
		}
		cout << ans << endl;
	}
	return 0;
}
E2 Palindrome de tres bloques (versión dura)
  • En comparación con E1, tiene un rango de datos mayor
  • Enumere la posición final de a a la izquierda y calcule la posición final de b a la derecha
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#define endl '\n'
using namespace std;
const int kN = 2e5 + 5, kM = 205;
int t,n,ans,a[kN],pre[kN][kM];
int main(void){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin >> t;
	while(t--){
		ans = 0;
		cin >> n;
		vector<vector<int>> at(kM); 
		for(int i = 1; i <= n; i++) cin >> a[i];
		for(int i = 1; i <= n; i++){//前缀和... 
			at[a[i]].push_back(i);//记录每个数的位置 
			for(int j = 1; j <= 200; j++){
				pre[i][j] = pre[i - 1][j] + (a[i] == j);
			}
		}
		//a所在位置,枚举l左端a的个数x,尾部倒数第x个a为r+1 
		for(int i = 1; i <= 200; i++){//枚举a 
			int sz = (int)at[i].size();
			for(int l = 0; l <= sz/2; l++){//左侧a的个数
				int r = sz - l - 1;//b区间的右侧第一个i的 
				if(l > r) break;
				else if(l == r) ans = max(ans,sz);//全a 
				else{
					int mx = 0;
					for(int j = 1; j <= 200; j++){//枚举b
						mx = max(mx,pre[at[i][r] - 1][j] - pre[at[i][l]][j]);
					}	
					ans = max(ans,2 * (l + 1) + mx);				
				} 
			}
		}
		cout << ans << endl;
	}
	return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/honey-cat/p/12751060.html
Recomendado
Clasificación