A1074

最初没有考虑到:
1、可能存在无效结点(不是从题目所给的头结点接下去的结点)
2、K个结点反转时,若是最后一组,则最后一个结点的下一结点是-1;若是倒数第二组,则要判断下一组结点个数是否刚好为K个.若<K个,则最后一个结点的下一结点为下一组结点的第一个结点地址;若=K个,则最后一个结点的下一结点为下一组结点的最后一个结点.

#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
struct node{
	int data;
	int pre;                                     //记录前驱地址 
	int next;
}nodes[100001];
int reverse(int first,int k){                    
	int temp=nodes[first].next;
	for(int i=2;i<k;i++){
		nodes[temp].pre=first;
		first=temp;
		temp=nodes[temp].next;
	}
	nodes[temp].pre=first;
	first=nodes[temp].next;
	nodes[first].pre=nodes[temp].next;
	printf("%05d %d %05d\n",temp,nodes[temp].data,nodes[temp].pre);
	temp=nodes[temp].pre;
	for(int i=1;i<k;i++){
		if(i==k-1){
			nodes[temp].pre=nodes[first].pre;
		}
		printf("%05d %d",temp,nodes[temp].data,nodes[temp].pre);
		if(nodes[temp].pre==-1){
			printf(" %d\n",nodes[temp].pre);
		}else{
			printf(" %05d\n",nodes[temp].pre);
		}
		temp=nodes[temp].pre;
	}
	return first;
}
int main(){
	#ifdef ONLINE_JUDGE
	#else
		freopen("1.txt","r",stdin);
	#endif
	int first,n,k,idx;
	scanf("%d %d %d",&first,&n,&k);
	for(int i=0;i<n;i++){
		scanf("%d",&idx);
		scanf("%d %d",&nodes[idx].data,&nodes[idx].next);
	}
	while(n>=k){
		first=reverse(first,k);
		n-=k;
	}
	while(first!=-1){
		printf("%05d %d",first,nodes[first].data);
		if(nodes[first].next==-1){
			printf(" %d\n",nodes[first].next);
		}else{
			printf(" %05d\n",nodes[first].next);
		}
		first=nodes[first].next;
	}
	return 0;
}

对上述的改进,思路:
1、定义静态链表(数组下标只是方便最开始定位结点地址,结构体中还应存储结点地址,方便之后排序结束,不丢失结点地址)
2、按照结点顺序作排序
3、作反转操作

#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
struct node{
	int address,data,next;
	int order;                                      //记录结点所在序号 
}nodes[100010];
bool cmp(node a,node b){
	return a.order<b.order;
}
int main(){
	#ifdef ONLINE_JUDGE
	#else
		freopen("1.txt","r",stdin);
	#endif
	for(int i=0;i<100010;i++){                     //初始化order,方便之后排序 
		nodes[i].order=100010;
	}
	int first,n,k,count=0;                         //count记录有效结点个数 
	scanf("%d%d%d",&first,&n,&k);
	for(int i=0;i<n;i++){                          //初始化静态链表 
		int address;
		scanf("%d",&address);
		scanf("%d%d",&nodes[address].data,&nodes[address].next);
		nodes[address].address=address;
	}
	while(first!=-1){                              //筛选有效结点 
		nodes[first].order=++count;
		first=nodes[first].next;
	}
	sort(nodes,nodes+100010,cmp);
	for(int i=k-1;i<count;i+=k){
		for(int j=i;j>i-k;j--){
			if(j==i-k+1){                                            //对每组最后一个数作判断处理 
				printf("%05d %d ",nodes[j].address,nodes[j].data);
				if(count-1-i==0){
					printf("-1\n");
				}else if(count-1-i<k&&count-1-i>0){
					printf("%05d\n",nodes[i+1].address);
				}else if(count-1-i>=k){
					printf("%05d\n",nodes[i+k].address);
				}
				break;
			}
			printf("%05d %d %05d\n",nodes[j].address,nodes[j].data,nodes[j-1].address);
		}
	}
	if(count%k!=0){                                                //对余数进行处理 
		for(int i=count/k*k;i<count;i++){
			printf("%05d %d",nodes[i].address,nodes[i].data);
			if(i==count-1){
				printf(" -1\n");
			}else{
				printf(" %05d\n",nodes[i+1].address);
			}
		}
	}
	return 0;
}

反转部分算法笔记中思路更加清晰明了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值