링크 된 목록을 반전 【PAT의 A1074】

상수 K와 단독으로 연결된리스트 L을 감안하면, 예를 들어 L.의 모든 K 요소 링크를, 역방향 해야하는 인 L 주어진 1 → 2 → 6 → 3 → 4 → 5, K = 3 인 경우 다음 출력해야 3 → 2 → 1 → 6 → 5 → 4; K 4, 당신이해야 출력 4 → 3 → 2 → 1 → 5 → 6 =합니다.

입력 사양 :
각 입력 파일이 하나의 테스트 케이스가 포함되어 있습니다. 각 경우에있어서, 첫 번째 행은 반전 될 서브리스트의 길이의 첫 번째 노드의 어드레스, 노드의 총 개수는 N 양 (≤10 ^ 5)와, 양의 K (≤N)를 포함 . 노드의 어드레스가 5 자리 부가 아닌 정수이고, NULL은 -1로 표시된다.

N 선을 따라 그리고, 각각의 형식의 노드를 설명

Address Data Next

주소는 노드의 위치이고, 데이터는 정수이며, 다음에 다음 노드의 위치이다.

출력 사양 :
각각의 경우를 들어, 출력 결과 목록을 연결 명령했다. 각 노드는 행을 점유하고, 입력과 동일한 형식으로 출력된다.

아이디어와 예제
내 바보 같은 아이디어, 그냥 익숙한 체인 작업에서, 메모를 아주 상세하게 설명한다 목록을 시뮬레이션하는 것입니다. 여기에 주로 때문에 살 수있는 내 샘플 책, 날 봐하지만 잘못된 응답이없는 경우,이 책의 첫 번째 샘플을 시도 할 수 있습니다, 샘플을 제공합니다. 나는 코드를 삽입하지 않습니다, 한 장소를 틀지 일을 완료하기 위해 역 함수에서 헤더 파일 알고리즘을 사용 후, 온라인보다 지능적인 접근 방식은 벡터 또는 배열 내부에 노드 목록의 순서에 따라,이 발생한다합니다.

11111 5 4
11111 1 22222
22222 3 33333
33333 4 -1
44444 5 55555
55555 2 11111

코드

#include <cstdio>
using namespace std;

struct Node{
	int data, Next;
}Nodes[100010];

int main(){
	int start, N, K;
	scanf("%d%d%d", &start, &N, &K);
	for(int i = 0; i < N; i++){
		int address;
		scanf("%d", &address);
		scanf("%d", &Nodes[address].data);
		scanf("%d", &Nodes[address].Next);
	}

	//cnt记录已经完成操作的节点个数,K个为一组,以为倍数
	//begin为组的开始下标
	//last是上一组的第一个元素
	int cnt = 0, begin = start, end = start, last;
	//还有没有完成操作的组
	while(true){
		//iterator用来遍历链表,before用来记录原序列中当前节点的前一个节点
		int iterator = begin, before = begin;
		//找这一组的最后一个节点
		end = begin;
		for(int i = 0; i < K - 1 && end != -1; i++)
			end = Nodes[end].Next;
		//如果end是-1说明这一组个数不足K,此时不调整顺序
		if(end == -1)
			break;
		//上一组最后一个节点连接这一组调整后的第一个节点
		//从第二组开始
		if(cnt > 0)
			Nodes[last].Next = end;
		last = begin;//记录这一组调整后的最后一个元素
		//第一组的最后一个元素为整个链的首节点
		if(cnt == 0)
			start = end;
		//修改begin为下一组第一个节点
		begin = Nodes[end].Next;
		for(int i = 0; i < K; i++){
			int tmp = Nodes[iterator].Next;//用来保存修改next之前的next
			if(i != 0)
				Nodes[iterator].Next = before;
			before = iterator;
			iterator = tmp;
		}
		cnt += K;
	}
	//防止最后一组不用调整,此时上一组的最后节点接该组第一个节点(未调整)
	if(cnt > 0)
		Nodes[last].Next = begin;

	for(int i = 0; i < N && start != -1; i++){
		if(i < N - 1 && Nodes[start].Next != -1)
			printf("%05d %d %05d\n", start, Nodes[start].data, Nodes[start].Next);
		else
			printf("%05d %d -1\n", start, Nodes[start].data);
		start = Nodes[start].Next;
	}

	return 0;
}
게시 30 개 원래 기사 · 원 찬양 1 ·은 10000 +를 볼

추천

출처blog.csdn.net/lvmy3/article/details/104215579