给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址、结点总个数正整数N(<= 105)、以及正整数K(<=N),即要求反转的子链结点的个数。结点的地址是5位非负整数,NULL地址用-1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address是结点地址,Data是该结点保存的整数数据,Next是下一结点的地址。
输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例:00100 6 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 12309 2 33218输出样例:
00000 4 33218 33218 3 12309 12309 2 00100 00100 1 99999 99999 5 68237 68237 6 -1
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct NODE{
int addr;
int data;
int nextAddr;
};
int main(){
int root,N,K;
vector <NODE> a(100000); //作为存储容器
cin>>root>>N>>K;
int i;
//input
for(i=0;i<N;i++){
NODE tt;
scanf("%d%d%d",&tt.addr,&tt.data,&tt.nextAddr);
a[tt.addr]=tt;
}
//sort
vector<NODE> b; //将链地址转化成顺序地址存储在容器中
while(root!=-1){
b.push_back(a[root]);
root=a[root].nextAddr;
}
//cout
int cc=0;
bool ff=true;
vector <NODE> c; //反转链表
while(cc+K<=b.size()){
int k=K;
while(k--){
c.push_back(b[cc+k]);
}
cc+=K;
}
while(cc<b.size()){ //将末尾不足k个元素进行顺序压入(不反转)
c.push_back(b[cc]);
cc++;
}
cc=0;
while(cc<c.size()){ //输出
if(cc==0){
printf("%05d %d ",c[cc].addr,c[cc].data);
}else{
printf("%05d\n%05d %d ",c[cc].addr,c[cc].addr,c[cc].data);
}
cc++;
}
cout<<"-1";
return 0;
}
Aden:这题考察了链表的知识,本来想要C语言的链表来搞定,后来发现太乱了,自己没那个能力,好在用C++的vector也可以实现存储以及变换元素的功能。
#include <cstdio>
#include <vector>
#include <iostream>
//#include <string.h>
#include <algorithm>
using namespace std;
struct Node{
int addr;
int a;
int next;
};
int main(){
// 读入
// 第一行
int root;
int n;
int k;
cin >> root >> n >> k;
// 其余行
vector<Node> inLst;
int posOf[100005];
int cnt = 0;
inLst.clear();
memset(posOf, -1, sizeof(posOf));
for (int i = 0; i < n; ++i) {
Node node;
cin >> node.addr >> node.a >> node.next;
inLst.push_back(node);
posOf[node.addr] = cnt++;
}
// 遍历
vector<Node> linkLst;
linkLst.clear();
int p = root;
int i;
for (i = 0; i < n; ++i) {
Node node = inLst[posOf[p]];
linkLst.push_back(node);
p = node.next;
if (p == -1) {
break;
}
}
// 变换(反转)
int time = (int)linkLst.size() / k;
for (int i = 0; i < time; ++i) {
reverse(linkLst.begin() + i * k, linkLst.begin() + (i + 1) * k);
}
// 反转方法2
/*
int cc=0;
bool ff=true;
vector <NODE> c; //反转链表
while(cc+K<=b.size()){
int k=K;
while(k--){
c.push_back(b[cc+k]);
}
cc+=K;
}
while(cc<b.size()){ //将末尾不足k个元素进行顺序压入(不反转)
c.push_back(b[cc]);
cc++;
}
*/
// 输出
int size = (int)linkLst.size();
for (int i = 0; i < size; ++i){
if (i == size - 1) {
printf("%05d %d -1\n",linkLst[i].addr,linkLst[i].a);
}else{
printf("%05d %d %05d\n",linkLst[i].addr,linkLst[i].a,linkLst[i+1].addr);
}
}
return 0;
}
Aden:这个程序和第一个大体上相同,只不是它是用数组来记录初始元素而第一个用的是容器vector.
#include<iostream>
#include<algorithm>
#include<vector>
#include <cstdio>
#include <string.h>
using namespace std;
struct Node{
int addr; //当前地址
int data;
int nextAddr; //下一个结点的地址
};
int main(){
int firstNode, N, K,i;
scanf("%d%d%d",&firstNode,&N,&K);
//cin >> firstNode >> N >> K;
vector <Node> inNode; //用来暂存输入的结点信息
inNode.clear();
int p[100005];
memset(p, -1, sizeof(p)); //将数组p中的元素都初始化为-1
int count = 0;
for ( i = 0; i < N; i++) //输入
{
Node temp;
scanf("%d%d%d",&temp.addr,&temp.data,&temp.nextAddr); //用scanf比cin所需时间少的多
//cin >> temp.addr >> temp.data >> temp.nextAddr;
inNode.push_back(temp);
p[temp.addr] = count++;
// p[temp.addr]=count;count++;
}
vector<Node> linkNode; //用来存取按指针地址排列的结点
linkNode.clear();
int q = firstNode;
for ( i = 0; i < N; i++) //遍历
{
Node node = inNode[p[q]];
linkNode.push_back(node);
//linkNode.push_back(inNode[p[q]]);
q=node.nextAddr;
//q = inNode[p[q]].nextAddr;
if (q == -1)
break;
}
//反转
int time = (int)linkNode.size() / K; //计算可有多少组需要反转的
//cout << "time" << time << endl;
for (int i = 0; i < time; ++i)
{
reverse(linkNode.begin() + i*K, linkNode.begin() + (i + 1) * K);
}
//输出
int size = (int)linkNode.size();
//cout << "size" << size<<endl;
for ( int i = 0; i < size; ++i)
{
if (i == size - 1)
printf("%05d %d -1\n", linkNode[i].addr, linkNode[i].data);
else
printf("%05d %d %05d\n", linkNode[i].addr, linkNode[i].data,linkNode[i+1].addr);
}
return 0;
}
Aden:这最后一个程序主要是反转的算法上与前两个有点区别。