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