1074 Reversing Linked List
题目大意:
给你一个链表,每隔k个节点翻转一下,输出翻转后的结果。
解题思路:
如果链表的长度正好是K的整数倍则全部要分段翻转,否则末尾的余数部分无需翻转。重点是翻转部分首尾指针的修改,可以定义一个变量保存未翻转前尾指针的下一个节点地址,每间隔K个节点修改首指针的指向地址。其他节点就反向修改即可。
代码如下:
#include<iostream>
#include<cstdio>
#include<fstream>
#include<set>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<iomanip>
#include<cstdlib>
#include<list>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
#define MOD 1000000007
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define meminf(a) memset(a,inf,sizeof(a))
//vector ::iterator it;
//set<int>::iterator iter;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
struct lis1//保存原有节点
{
int key,next;
}nod1[110000];
struct lis2//保存筛选后的节点
{
int address,key,next;
}nod2[110000];
int main()
{
int a1,d1,n1;
scanf("%d %d %d",&a1,&d1,&n1);
for(int i=0;i<d1;i++)
{
int t1,t2,t3;
scanf("%d %d %d",&t1,&t2,&t3);
nod1[t1].key=t2;nod1[t1].next=t3;
}
int tmp=a1,num=0;
while(tmp!=-1)//从给定头指针遍历后得到的链表,将节点依次放入
{
nod2[num].address=tmp;nod2[num].key=nod1[tmp].key;
nod2[num].next=nod1[tmp].next;num++;
tmp=nod1[tmp].next;
}
int k1,k2,k3;
if(num%n1)//有余数,也末尾部分无需翻转
{
int sum=num-num%n1;//需要翻转部分的末尾
k1=nod2[sum].address,k2=sum-1;//分别是末尾节点的指针,开始翻转节点的下标
}
else//都要翻转
{
k1=-1;k2=num-1;k3=k2;
}
while(k2>=0)//遍历链表
{
if(k2%n1)
{
nod1[nod2[k2].address].next=nod2[k2-1].address;//反向修改指针
}
else//翻转了K个,修改首尾节点指针
{
nod1[nod2[k2].address].next=k1;
k1=nod2[k3].address;
k3=k2-1;//保留翻转部分的头指针
}
k2--;
}
int add=nod2[n1-1].address;//翻转后的头指针
while(add!=-1)
{
if(nod1[add].next!=-1)
printf("%05d %d %05d\n",add,nod1[add].key,nod1[add].next);
else printf("%05d %d -1\n",add,nod1[add].key);
add=nod1[add].next;
}
// cin.tie(0);
// freopen("test.txt","r",stdin);
// freopen("output.txt","w",stdout);
return 0;
}