2021 Niu Guest Winter Holiday Algorithm Campo de treinamento básico 2 F. Niu Niu e triagem de troca (inversão de fila dupla)

F. Niu Niu e Triagem de Classificação

Link do título: https://ac.nowcoder.com/acm/contest/9982/F

Descrição do título:

Niuniu possui um array, os elementos do array são arrays de 1 a n, ou seja, o valor do array está na faixa de 1 a n, e cada número aparece apenas uma vez.
Niuniu deseja alterar a matriz em ordem crescente, ele pode realizar as seguintes operações.

Primeiro, ele deve determinar um comprimento k, o intervalo de k está entre 1 e n.
Em seguida, ele executará várias operações. Em cada rodada de operação, ele pode selecionar uma submatriz de comprimento k e, em seguida, realizar a operação de inversão de intervalo.

Ele pode fazer qualquer número de operações, mas é necessário selecionar um intervalo de submatriz que satisfaça li ≤ li + 1 a cada vez, e o comprimento do intervalo é igual ao k selecionado no início, o que significa que uma vez determinada operação seleciona uma determinada posição da matriz. Execute a operação de reversão do intervalo e a posição da reversão do intervalo da próxima vez estará mais à direita do que da última vez.

Niuniu descobriu que nem sempre há um k que pode ordenar a classificação do array. Diga a Niuniu se há um k que pode completar a classificação sob a condição de satisfazer as regras.

Insira uma descrição:

Insira um número inteiro positivo n (1≤n≤10 ^ 5) na primeira linha para indicar o tamanho da matriz.
Em seguida, produza uma linha de n inteiros positivos para representar um arranjo, ou seja, o tamanho de cada número varia de 1 a n e cada inteiro positivo aparece apenas uma vez.

Descrição de saída:

Se houver pelo menos um k que pode permitir que Niuniu conclua a classificação, envie um "sim" em uma linha e, em seguida, inicie outra linha para produzir ak que possa satisfazer a classificação. O intervalo de k deve estar entre [ 1, n], se houver mais solução, você pode gerar qualquer uma.

Pelo contrário, se não houver k para completar a classificação, envie um "não" diretamente em uma linha.

Exemplo 1:

Entrada
5
5 2 1 4 3
Saída
sim
3
Descrição
Primeiro inverta o intervalo [1,3] e, em seguida, inverta o intervalo [3,5]

Exemplo 2:

Entrada
5
1 2 3 4 5
Saída
sim
1
Descrição
Como foi pedido originalmente, não há necessidade de fazer nenhuma operação, portanto, apenas envie a k.

Exemplo 3:

Entrada
5
5 4 3 2 1
Saída
sim
5
Descrição
Inverter diretamente o intervalo [1,5]
Observações:
Se houver várias soluções, você pode produzir qualquer k na faixa de [1, n].

Ideias para resolução de problemas:

Uma vez que o intervalo de cada lance deve estar no lado direito da vez anterior, se você não virar 1 para a posição pela primeira vez, então 1 não retrocederá. Portanto, o valor de k que pode ser obtido é: a diferença entre a posição de 1 e o valor de 1 (se o 1 estiver no lugar, é a diferença entre a posição de 2 e a diferença entre a posição de ie a posição de i ).
Em seguida, considere quando você precisa inverter : quando o valor da posição atual i não é i, considere inverter o intervalo de comprimento k começando de i, e
então considere em quais circunstâncias não há solução : a i-ésima posição não é i ainda ou ambos estão invertidos A posição imóvel está errada.
Você pode usar uma matriz para simular se deseja transformar o intervalo em k e usar um número para marcar a ordem ou a ordem inversa (virar o número par de vezes ou o número ímpar de vezes).
Ao usar i-1 para i, primeiro remova i-1 do lado esquerdo da sequência. Neste momento, é necessário julgar se a posição de i-1 está correta e, em seguida, julgar se o i atual mais à esquerda precisa ser invertido .

código mostrado abaixo:

Método 1:

#include <iostream>
#include<algorithm>
using namespace std;

struct d{
    
    
	int l,r,flag;
	int qu[200010];
	void reverse(){
    
    
		flag^=1;
	}
	void push_back(int x){
    
    
		if (flag == 0)  qu[r++]=x;
		else qu[--l]=x;
	}
	int front(){
    
    
		if (flag == 0)  return qu[l];
		else return qu[r-1];
	}
	void pop_front(){
    
    
		if (flag == 0)  l++;
		else r--;
	}
}q;
int main(){
    
    
	int n;
	int a[100010];
	int pos[100010];
	cin>>n;
	for (int i=1;i<=n;i++){
    
    
		cin>>a[i];
		pos[a[i]]=i;
	}
	int k=0;
	for (int i=1;i<=n;i++){
    
    
		if(i != pos[i]){
    
    
			k = pos[i]-i+1;
			break;
		}
	}
	if (k==0){
    
    
		cout <<"yes"<<endl<<"1";
		return 0;
	}
	bool ans=1;
	q.l=100000;q.r=100000;
	for (int i=1;i<=k;i++)
		q.push_back(a[i]);
	for (int i=1;i<=n;i++){
    
    
		if (q.front()!=i){
    
    
			q.reverse();
			if (q.front()!=i){
    
    
				ans=0;
				break;
			}
		}
		q.pop_front();
		q.push_back(a[i+k]);
	}
	if (ans) cout <<"yes"<<endl<<k;
	else cout <<"no"<<endl;
	return 0;
}

Método 2:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[100010]={
    
    0};
int pos[100010]={
    
    0};
 
int main()
{
    
    
    int n ;
    cin>>n;
    int k=1;
    for(int i=1;i<=n;i++){
    
    
        cin>>a[i];
        pos[a[i]]=i;
    }
    for(int i=1;i<=n;i++){
    
    
        if(i!=pos[i]){
    
    
            k=pos[i]-i+1;
            break;
        }
    }  
    for(int i=1;i<=n;i++){
    
    
        if(a[i]!=i&&i+k-1<=n){
    
    
            for(int j=1;j<=k/2;j++)
            {
    
    
                swap(a[i+j-1],a[i+k-j]);
            }
        }
        if(a[i]!=i){
    
    
            cout<<"no"<<endl;
            return 0;
        }
    }
    cout<<"yes"<<endl;
    cout<<k<<endl;
    return 0;
}

Acho que você gosta

Origin blog.csdn.net/weixin_45894701/article/details/113664097
Recomendado
Clasificación