pat Basic 1110 переворот блоков

Учитывая односвязный список L, мы рассматриваем каждый K узлов как блок ( если в конце связанного списка меньше K узлов, он также считается блоком), напишите программу, которая поменяет местами ссылки всех блоки в L. Например: учитывая, что L равно 1→2→3→4→5→6→7→8 и K равно 3, выход должен быть 7→8→4→5→6→1→2→3.

Формат ввода:

Каждый вход содержит 1 тестовый пример. В первой строке каждого тестового примера указан адрес первого узла, общее количество узлов, положительное целое число N (≤10^5) и положительное целое число K (≤N), которое представляет собой размер блока. Адрес узла представляет собой 5-битное неотрицательное целое число, а NULL-адрес представлен как -1.

Далее идут N строк, и формат каждой строки следующий:

Address Data Next

где Address– адрес узла, Data– целочисленные данные, сохраненные узлом, – Nextадрес следующего узла.

Выходной формат:

Для каждого тестового примера обратносвязанный список выводится последовательно, при этом каждый узел занимает одну строку, а формат тот же, что и входной.

Пример ввода:

00100 8 3
71120 7 88666
00000 4 99999
00100 1 12309
68237 6 71120
33218 3 00000
99999 5 68237
88666 8 -1
12309 2 33218

Выходной образец:

71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1

Идеи решения проблем:

Этот вопрос также является операцией связанного списка. Две функции BuildList и PrintList, которые я написал в 1105, можно использовать повторно напрямую. Или мне следует сначала поместить данные в двумерный массив, а затем извлечь из него узлы, чтобы сформировать исходный связанный массив? список. Блок представлен структурой Block с двумя указателями внутри, указывающими на начало и конец блока. В этот момент блок становится большим указателем, и для выполнения переворота необходимы три блока pb1, pb2 и pb3. pb3 идет впереди, а хвост pb2 указывает на голову pb1. Флип завершен, и тогда каждый блок Блоки перемещаются вперед один за другим. При написании кода обратите внимание на нулевые указатели и сделайте необходимые выводы.

#include <stdio.h>
#include <stdlib.h>
#define MAXN 100000

typedef struct node *PtrN;
typedef PtrN List;
struct node {
	int address, data, next;
	PtrN link;
};

typedef struct Bnode *Block;
struct Bnode {
	PtrN front, rear;
};

PtrN ReverseBlock(Block pb1, Block pb2) { 
	pb2->rear->link = pb1->front;
	if ( pb1->front )
		pb2->rear->next = pb1->front->address;
	return pb2->front;
}

void Follow(Block pb1, Block pb2) {
	pb1->front = pb2->front;
	pb1->rear = pb2->rear;
}

void Forward(Block pb3, int steps) {
	if ( !pb3->rear->link ) return;
	pb3->front = pb3->rear->link;
	PtrN mv = pb3->rear->link;
	while ( mv->link && steps ) {
		mv = mv->link;
		--steps;
	}
	pb3->rear = mv;
}

List BuildList(int head, int temp[][MAXN]) {
	if ( head == -1 ) return NULL;
	List l, p, tmp;
	l = (List)malloc(sizeof(struct node));
	l->address = head;
	l->data = temp[0][head];
	l->next = temp[1][head];
	p = l;
	while ( p->next != -1 ) {
		tmp = (List)malloc(sizeof(struct node));
		tmp->address = p->next;
		tmp->data = temp[0][tmp->address];
		tmp->next = temp[1][tmp->address];
		p->link = tmp;
		p = p->link;
	}
	p->link = NULL;

	return l;
}

void PrintList(List l) {
	if ( !l ) return;
	while ( l->link ) {
		printf("%05d %d %05d\n", l->address, l->data, l->next);
		l = l->link;
	}
	printf("%05d %d -1\n", l->address, l->data);
}

int main(int argc, const char *argv[]) {
	int head, N, K, addr, data, next;
	int temp[2][MAXN];

	if ( scanf("%d%d%d", &head, &N, &K)==EOF ) printf("error\n");
	while ( N-- ) {
		if ( scanf("%d %d %d", &addr, &data, &next)==EOF ) printf("error\n");
		temp[0][addr] = data;
		temp[1][addr] = next;
	}
	List l1 = BuildList(head, temp);
	PtrN empty = (PtrN)malloc(sizeof(struct node));
	Block pb1 = (Block)malloc(sizeof(struct Bnode));
	Block pb2 = (Block)malloc(sizeof(struct Bnode));
	Block pb3 = (Block)malloc(sizeof(struct Bnode));
	empty->link = l1;
	pb3->front = NULL;
	pb3->rear = empty;
	Follow(pb2, pb3);
	Follow(pb1, pb2);
	Forward(pb3, K-1);
	while ( pb3->rear->link ) {
		Follow(pb2, pb3);
		Forward(pb3, K-1);
		l1 = ReverseBlock(pb1, pb2);
		Follow(pb1, pb2);
	}
	l1 = ReverseBlock(pb2, pb3);
	free(empty); free(pb3); free(pb2); free(pb1);
	PrintList(l1);

	return EXIT_SUCCESS;
}

Guess you like

Origin blog.csdn.net/herbertyellow/article/details/127034431
Recommended