此题最坑的,就是特殊情况太多,正常人考虑不到。
正常人思维最多拿三个点,之后的三个都是外星人需要拿的点。
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
// 针对本题的静态链表的结构
struct Node{
bool exist;
int data;
int next;
int address;
Node(){
exist = false;
data = 0;
next = -1;
}
}node[100020];
bool cmp(Node a, Node b){
// a b 两者之中任意一个不存在,a存在把a放前面,a不存在把b放前面
// 都不存在时,把b放前面
if((!a.exist != !b.exist) || (!a.exist && !b.exist)){
return a.exist;
} else{
return a.data < b.data;
}
}
int main(){
// 这段注释是测试cmp的效果 达到有效节点排在前面就好了
// Node node[5];
// node[0].exist = true;
// node[0].data = -1;
// node[1].exist = false;
// node[2].exist = false;
// node[3].exist = false;
// node[4].exist = true;
// node[4].data = 32;
// sort(node, node + 5, cmp);
// for(int i = 0; i < 5; i++){
// cout<<node[i].exist<<' ';
// cout<<node[i].data <<endl;
// }
int N, head;
scanf("%d %d", &N, &head);
// 不应该这样想 应该按照count来
// if(N == 0){
// printf("%d %05d\n", N, head);
// return 0;
// }
int tmpAddress, tmpData, tmpNext;
for(int i = 0; i < N; i++){
scanf("%d %d %d", &tmpAddress, &tmpData, &tmpNext);
node[tmpAddress].data = tmpData;
node[tmpAddress].next = tmpNext;
node[tmpAddress].address = tmpAddress; //增加地址位
}
// 题目可能有无效节点 需要先遍历一遍
// 第二个和倒数两个测试点是无效节点的
int p = head;
int total = 0;
while(p != -1){
node[p].exist = true;
p = node[p].next;
total ++;
}
// 这个是遍历之后实际节点没有的情况 必须要考虑到 最后一个测试用例是考这个点
if(total == 0){
printf("0 -1");
return 0;
}
sort(node, node + 100020, cmp);
// 最终只需要做一个 “假的排序” 即顺序输出其下标和后面的address位
// 来达到 看上去排序了 的目的
printf("%d %05d\n", total, node[0].address);
for(int i = 0; i < total; i++){
if( i < total - 1)
printf("%05d %d %05d\n", node[i].address, node[i].data, node[i + 1].address);
else
printf("%05d %d %d", node[i].address, node[i].data, -1);
}
return 0;
}