按每单元 k 个结点来反转链表。
如,链表为1 -> 2 -> 3 -> 4 -> 5 -> 6,并且k = 4时
结果应为4 -> 3 -> 2 -> 1 -> 5 -> 6
1. 注意到,最后除不尽的那个单元是不翻转的。一开始题目没认真读,囧。
2. 测试点6考察的是输入的结点有的不在链表上的结果。我用dfs做时,就需要重新计算结点总数来限制搜索的深度。
#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
using namespace std;
struct Node
{
Node() {}
Node(int data, int next): m_data(data), m_next(next) {}
int m_data;
int m_next;
};
Node node[100010];
int head, n, k;
int add, data, nexx, now;
int dfs(const vector<int>& vt, int level)
{
if (level == 0)
{
head = vt.back();
}
vector<int> new_vt;
if (level < n/k -1)
{
int now = node[vt.back()].m_next;
for (int i = 0; i < k; ++ i)
{
new_vt.push_back( now );
now = node[now].m_next;
}
}
int end = node[vt[k-1]].m_next;
for (int i = k-1; i > 0; -- i)
{
node[vt[i]].m_next = vt[i-1];
}
if (level < n/k - 1)
{
node[vt[0]].m_next = dfs(new_vt, level+1);
} else
{
node[vt[0]].m_next = end; // 此时end == 后面的链表头 或 -1
}
return vt.back();
}
int count_n()
{
int cnt = 0;
now = head;
while (now != -1)
{
++ cnt;
now = node[now].m_next;
}
return cnt;
}
int main()
{
scanf("%d%d%d", &head, &n, &k);
for (int i = 0; i < n; ++ i)
{
scanf("%d%d%d", &add, &data, &nexx);
node[add].m_data = data;
node[add].m_next = nexx;
}
n = count_n();
if (n == 0)
{
return 0;
}
vector<int> vt;
now = head;
for (int i = 0; i < k; ++ i)
{
vt.push_back(now);
now = node[now].m_next;
}
dfs(vt, 0);
now = head;
while (node[now].m_next != -1)
{
printf("%05d %d %05d\n", now, node[now].m_data, node[now].m_next);
now = node[now].m_next;
}
printf("%05d %d %d\n", now, node[now].m_data, node[now].m_next);
return 0;
}
http://blog.csdn.net/acm_ted/article/details/20406485
这份代码比我的短。