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:
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<iostream>
using namespace std;
const int maxn=100099;
struct node
{
int address,data,next;
}Node[maxn],Node1[maxn],Node2[maxn];
int first,n,k;
int main()
{
cin >> first >> n >> k;
for(int i=0; i<n; i++)
{
int a;
cin >> a;
cin >> Node[a].data >> Node[a].next;
Node[a].address=a;
}
int cnt=0;
while(first!=-1)
{
Node1[cnt].address=Node[first].address;
Node1[cnt].data=Node[first].data;
Node1[cnt].next=Node[first].next;
first=Node[first].next;
cnt++;
}
bool flag=true;
int cnt1=0;
for(int i=n-n%k; i>=0; i-=k)
{
if(flag)
{
for(int j=i; j<=n-1; j++)
{
Node2[cnt1].address=Node1[j].address;
Node2[cnt1].data=Node1[j].data;
cnt1++;
}
flag=false;
}
else
{
for(int j=i; j<=i+k-1; j++)
{
Node2[cnt1].address=Node1[j].address;
Node2[cnt1].data=Node1[j].data;
cnt1++;
}
}
}
for(int i=0; i<cnt1; i++)
{
if(i==cnt1-1)
printf("%05d %d -1",Node2[i].address,Node2[i].data);
else
printf("%05d %d %05d\n",Node2[i].address,Node2[i].data,Node2[i+1].address);
}
return 0;
}
7-2 Merging Linked Lists (25 分)
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
int n, h1, h2;
int e[N], ne[N]; //e的下标是地址,元素是值;ne的下标是地址,元素是下个地址
vector<int> l1, l2;
int main()
{
scanf("%d%d%d", &h1, &h2, &n);
while (n--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
e[a] = b, ne[a] = c;
}
for (int i = h1; ~i; i = ne[i]) l1.push_back(i);
for (int i = h2; ~i; i = ne[i]) l2.push_back(i);
if (l1.size() <= l2.size()) swap(l1, l2); //一直保持l1是长的
reverse(l2.begin(), l2.end()); //翻转l2
for (int i = 0, j = 0; i < l1.size(); i++) //i去遍历l1,j去遍历l2
{
printf("%05d %d ", l1[i], e[l1[i]]);
if (i & 1 && j < l2.size()) //i&1 = (i+1)%2==0
{
printf("%05d\n%05d %d ", l2[j], l2[j], e[l2[j]]);
j++;
}
if (i + 1 == l1.size())
printf("-1\n");
else
printf("%05d\n", l1[i + 1]);
}
return 0;
}
Splitting A Linked List (25 分)
#include<iostream>
using namespace std;
const int maxn=100010;
int e[maxn],ne[maxn];
int first,n,k;
struct node
{
int address;
int data;
}Node[maxn];
int cnt;
int main()
{
cin >> first >> n >> k;
for(int i=0; i<n; i++)
{
int address;
cin >> address;
cin >> e[address] >> ne[address];
}
int first1,first2;
first1=first2=first;
while(first1!=-1)
{
if(e[first1]<0)
{
Node[cnt].address=first1;
Node[cnt].data=e[first1];
cnt++;
}
first1=ne[first1];
}
while(first2!=-1)
{
if(e[first2]<=k && e[first2]>=0)
{
Node[cnt].address=first2;
Node[cnt].data=e[first2];
cnt++;
}
first2=ne[first2];
}
while(first!=-1)
{
if(e[first]>k)
{
Node[cnt].address=first;
Node[cnt].data=e[first];
cnt++;
}
first=ne[first];
}
for(int i=0; i<cnt-1; i++)
printf("%05d %d %05d\n",Node[i].address,Node[i].data,Node[i+1].address);
printf("%05d %d -1\n",Node[cnt-1].address,Node[cnt-1].data);
return 0;
}