个人学习记录,代码难免不尽人意。
Given a singly linked list L. Let us consider every K nodes as a block (if there are less than K nodes at the end of the list, the rest of the nodes are still considered as a block). Your job is to reverse all the blocks in L. For example, given L as 1→2→3→4→5→6→7→8 and K as 3, your output must be 7→8→4→5→6→1→2→3.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10 5 ) which is the total number of nodes, and a positive K (≤N) which is the size of a block. The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
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
Sample Output:
71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<stack>
#include<string>
#include<vector>
using namespace std;
const int maxn=100010;
struct node{
int address;
int data;
int next;
}Node[maxn];
int nextnode[maxn];
stack<vector<int> > s;
stack<vector<int> > temp;
int main(){
int begin,n,k;
scanf("%d %d %d",&begin,&n,&k);
for(int i=0;i<n;i++){
int address,data,next;
scanf("%d %d %d",&address,&data,&next);
Node[address].address=address;
Node[address].data=data;
Node[address].next=next;
}
int op=begin;
int count=0;
vector<int> v;
while(op!=-1){
if(count!=k){
v.push_back(op);
count++;
op=Node[op].next;
}
else{
s.push(v);
v.clear();
count=0;
}
}
if(count!=0) s.push(v);//当时做的时候这道题我记得这里加上但是第一题却忘了,汗
temp=s;
int cnt=0;
temp.pop();
while(!temp.empty()){
vector<int> v=temp.top();
temp.pop();
nextnode[cnt++]=v[0];
}
nextnode[cnt]=-1;
int cal=0;
while(!s.empty()){
vector<int> v=s.top();
s.pop();
for(int j=0;j<v.size();j++){
int address=v[j];
if(j!=v.size()-1)
printf("%05d %d %05d\n",address,Node[address].data,Node[address].next);
else if(cal!=cnt)
printf("%05d %d %05d\n",address,Node[address].data,nextnode[cal++]);
else if(cal==cnt)
printf("%05d %d %d\n",address,Node[address].data,nextnode[cal++]);
}
}
}
做了这么多链表的题,我算是总结出了一个经验,那就是尽量不要暴力去做,尽量不要直接对链表进行一些操作,而是试图通过数组排序的方法来做!(当然题目特殊的话还是要手动模拟)。
我的做法就是,题目让我们将链表按照“块”来逆转,但是块内顺序不变,那这就好做了,我们遍历一遍数组,然后将每个块的节点地址都保存下来,因为是逆转,所以我们可以用stack里面内嵌vector来存储,然后出栈就是逆序的!到这里我们已经解决了80%的问题了,还需要解决最后一个问题——next,这样直接输出的话块与块之间的next值对不上,所以我们可以提前遍历一遍stack,存储从第二个块开始每个块第一个节点的地址(最后一个手动赋值为-1),输出的时候判断一下即可,具体可以看我代码。