Ejercicios de estrategia de dividir y conquistar para el diseño y análisis de algoritmos (parte 2)

Estrategia de dividir y conquistar para resolver el problema seis: problema de cronograma por turnos

Descripción del problema

Suponiendo que n = 2 ^ k jugadores quieren jugar todos contra todos, diseñe un programa de juego que cumpla con los siguientes requisitos:

  • Cada jugador debe competir con otros n-1 jugadores una vez cada uno
  • Cada jugador solo puede competir una vez al día
  • Un total de n-1 días en el round robin

Los ejemplos de 8 jugadores son los siguientes:
Inserte la descripción de la imagen aquí

análisis del problema

Se puede analizar a partir de la imagen de ejemplo que este horario se puede generar copiando en diagonal en la unidad más pequeña, mire la imagen de demostración que hice:
Inserte la descripción de la imagen aquí

Implementación de algoritmos

#include <iostream>
#include <cmath>
#include <algorithm>

#define N 100
using namespace std;
//存放日程表
int schedule[N][N];
//拷贝方块
void copyBox(int,int,int,int,int);
//生成循环赛日程表
void generateRRS(int);
int main()
{
    
    
    int n;
    cout<<"请输入参加人数:";
    cin>>n;
    generateRRS(n);
    for(int i=0;i<n;i++){
    
    
        for(int j=0;j<n;j++){
    
    
            cout<<schedule[i][j]<<"\t";
        }
        cout<<"\n\n";
    }
    return 0;
}
/*
    拷贝方块实现
    toi,toj为拷贝到的位置的左上角在二维数组中的位置
    fromi,fromj为原始的位置的左上角在二维数组中的位置
    size为拷贝方块的边长
*/
void copyBox(int toi,int toj,int fromi,int fromj,int size){
    
    
    for(int i=0;i<size;i++)
        for(int j=0;j<size;j++)
            schedule[toi+i][toj+j] = schedule[fromi+i][fromj+j];
}
/*
    生成循环赛日程表
    n=2^k,选手个数,参数错误则提示并结束程序
*/
void generateRRS(int n){
    
    

    double temp = log(n)/log(2);
    if(temp != (int)temp || temp == 0){
    
    
        cout<<"函数参数异常!";
        exit(0);
    }

    for(int i=0;i<n;i++)    //初始化第一行
		schedule[0][i]=i+1;

    for(int size=1;size<n;size*=2)
 		for(int i=0;i<n;i+=2*size)	{
    
    
			copyBox(size,size+i,0,i,size);     //左上角拷贝到右下角
			copyBox(size,i,0,size+i,size);     //右上交角拷贝到左下角
		}

}

Estrategia de dividir y conquistar para resolver el problema siete: cubierta de tablero especial

Descripción del problema

  En un tablero de ajedrez compuesto por cuadrados de 2k × 2k, exactamente un cuadrado es diferente de los otros cuadrados, este cuadrado se llama cuadrado especial y el tablero se llama tablero de ajedrez especial.
  En el problema de la cobertura del tablero de ajedrez, se utilizarán 4 formas diferentes de dominó en forma de L, como se muestra en la figura, para cubrir todos los cuadrados de un tablero de ajedrez especial dado, excepto los cuadrados especiales, y dos dominós en forma de L no se superpondrán.
  Para un tablero de ajedrez especial dado, diseñe un esquema de cobertura de tablero de ajedrez.
    Por ejemplo:
    Entrada:
      2 // k, la longitud del lado del tablero de ajedrez es 2k
      0 1 // Las coordenadas del cuadrado especial (usando una matriz de 2k * 2k para representar un tablero de ajedrez)
    Salida:
     2 0 3 3
     2 2 1 3
     4 1 1 5
     4 4 5 5

análisis del problema

Inserte la descripción de la imagen aquí
La imagen de arriba es una cubierta especial de tablero de ajedrez de 4 * 4 completada. Analicémosla un poco. Si queremos cubrirla de manera ordenada, el problema es descomponer el problema en subproblemas suficientemente pequeños como este:
Inserte la descripción de la imagen aquí
porque queremos usar el mismo código numérico para expresar, Debe dividirse en más pequeños, cuando solo haya una casilla vacía, complete los números de dominó correspondientes si no es una casilla especial.
En una descomposición, necesitamos poner un número en una esquina especial
  ,
  agregarlo a la
  esquina inferior derecha de la esquina superior izquierda, agregar la
  esquina inferior izquierda de la esquina superior derecha, agregar la esquina superior izquierda de la esquina inferior derecha, agregar la esquina superior derecha de la esquina inferior izquierda y
continuar Esta estrategia todavía se utiliza durante la descomposición.
Inserte la descripción de la imagen aquí

Implementación de algoritmos

#include <iostream>
#include <cmath>
#include <algorithm>
#define N 100
using namespace std;

//棋盘
int chessboard[N][N];
//骨牌编号
int gno = 0;

//覆盖特殊棋盘函数
void putChessboard(int,int,int,int,int);

int main()
{
    
    
    //棋盘大小
    int n;
    //特殊方格行列号
    int si,sj;

    cout<<"请输入棋盘大小:";
    cin>>n;
    //检测一下n
    double temp = log(n)/log(2);
    if(temp != (int)temp || temp == 0){
    
    
        cout<<"棋盘大小异常!";
        exit(0);
    }

    cout<<"请输入特殊方格位置:";
    cin>>si>>sj;

    putChessboard(0,0,si,sj,n);

    for(int i=0;i<n;i++){
    
    
        for(int j=0;j<n;j++){
    
    
            cout<<chessboard[i][j]<<"\t";
        }
        cout<<"\n\n";
    }
    return 0;
}
/*
    覆盖特殊棋盘函数
    ti,tj 棋盘左上角的坐标
    si,sj 特殊方格的位置
    size 棋盘宽度 不符提示并退出程序
*/
void putChessboard(int ti,int tj,int si,int sj,int size){
    
    
    if(size == 1) return;
    //当前骨牌编号
    int no = ++gno;

    int mSize = size/2; // 分割棋盘

    //处理左上角棋盘
    if(si<ti+mSize && sj<tj+mSize)
        putChessboard(ti,tj,si,sj,mSize);
    else{
    
    
        chessboard[ti+mSize-1][tj+mSize-1] = no;
        putChessboard(ti,tj,ti+mSize-1,tj+mSize-1,mSize);
    }
    //处理左下角棋盘
    if(si>=ti+mSize && sj<tj+mSize)
        putChessboard(ti+mSize,tj,si,sj,mSize);
    else{
    
    
        chessboard[ti+mSize][tj+mSize-1] = no;
        putChessboard(ti+mSize,tj,ti+mSize,tj+mSize-1,mSize);
    }
    //处理右上角棋盘
    if(si<ti+mSize && sj>=tj+mSize)
        putChessboard(ti,tj+mSize,si,sj,mSize);
    else{
    
    
        chessboard[ti+mSize-1][tj+mSize] = no;
        putChessboard(ti,tj+mSize,ti+mSize-1,tj+mSize,mSize);
    }
    //处理右下角棋盘
    if(si>=ti+mSize && sj>=tj+mSize)
        putChessboard(ti+mSize,tj+mSize,si,sj,mSize);
    else{
    
    
        chessboard[ti+mSize][tj+mSize] = no;
        putChessboard(ti+mSize,tj+mSize,ti+mSize,tj+mSize,mSize);
    }
}

Recomendado por otros artículos de este blog

Ejercicios de estrategia de dividir y conquistar para el diseño y análisis de algoritmos (activado)

Estrategia de dividir y conquistar para el diseño y análisis de algoritmos

Diseño de algoritmos y análisis de ejercicios de algoritmos recursivos (abajo)

Diseño de algoritmos y análisis de ejercicios de algoritmos recursivos (encendido)

Problema del triángulo digital en el diseño y análisis de algoritmos

Diseño y análisis de algoritmos de ZOJ2104- Let the Balloon Rise

Diseño y análisis de algoritmos de cola de prioridad y solución ZOJ1167

Supongo que te gusta

Origin blog.csdn.net/L333333333/article/details/102640726
Recomendado
Clasificación