题目链接1:点击打开链接
题目链接2:点击打开链接
题目大意:略。
解题思路:
1、输入初始化
2、从头走到尾一遍,统计有效个数,并把最后一个结点的 next = -1
3、从头开始,每 k 个反转链表并将反转后的结果传到最终输出的容器里(注意:不到 k 个无需反转,不要忘记把每段反转以后的新的链表接起来)
4、注意 k==1 的情况,有两个点(3、4 测试点)是搞这个的,我是自己特判处理的(因为无需反转)。换句话说:一是结点数能整除 K 的,二是不能整除的。当能整除时,一定注意调整最后的那个-1。以及 K 也有可能大于有效节点数。
5、考虑 cout、cin 容易超时的问题,用 scanf、printf 替代。
未 AC 代码(测试点5 WA,就是那组数据很大的那组,真不知道什么情况没考虑到~)
/
#include<bits/stdc++.h> #include<cmath> #define mem(a,b) memset(a,b,sizeof a); #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=1e5+10; struct node { int id,cur,nx,pre; }nds[maxn], ndrs[maxn]; int l, len, F; node tnd; void showInit(int h) { puts("-----------------------"); int cur=h; for(int i=0;i<len;i++) { printf("%05d %d %05d\n",nds[cur].cur,nds[cur].id,nds[cur].nx); cur=nds[cur].nx; } puts("-----------------------"); } void reverseList(int s, int e) { if(l>0) ndrs[l-1].nx=e; int cur=e,pre,jde=nds[s].pre; while(1) { pre=nds[cur].pre; nds[cur].nx=pre; ndrs[l++]=nds[cur]; if(jde==pre) return; cur=pre; } } int main() { int h,n,k; while(~scanf("%d%d%d",&h,&n,&k)) { int cur,id,nx; for(int i=0;i<n;i++) { scanf("%d%d%d",&cur,&id,&nx); nds[cur].id=id, nds[cur].cur=cur, nds[cur].nx=nx; } // if(h==-1){ puts("-1"); continue; } // 从头走到尾一遍,统计有效个数,并把它们各自的前置地址找到,以及把最后一个结点的 next = -1 int pre=-2; cur=h; len=0; int f=1; while(1) { nds[cur].pre=pre; pre=cur; cur=nds[cur].nx; len++; if(len==k) F=pre; if(cur==-1 || nds[cur].id==0) { nds[pre].nx=-1; break; } } if(len<k) k=1; // printf("Last == cur : %05d, nx : %d\n",pre,nds[pre].nx); // cout<<len<<endl; // showInit(h); // 从头开始,每 k 个反转链表并将反转后的结果传到最终输出的容器里(注意:不到 k 个无需反转,而且每次把上一组的衔接修复好) l=0; cur=h; int th, t=0, tcur; while(k!=1) // k==1 无需反转 { cur=nds[cur].nx; t++; if(t==k-1 && cur!=-1) { // printf("h: %05d, t: %05d\n",h,cur); t=0; th=nds[cur].nx; reverseList(h,cur); tcur=cur=h=th; // show(); } if(cur==-1) break; } if(len%k!=0) ndrs[l-1].nx=tcur; // 修复好最后一组未修复的 while(len%k!=0 && tcur!=-1) { ndrs[l++]=nds[tcur]; tcur=nds[tcur].nx; } if(k==1) // 特判 { while(1) { ndrs[l++]=nds[cur]; cur=nds[cur].nx; if(cur==-1) break; } } for(int i=0;i<l;i++) { if(i==len-1) printf("%05d %d -1\n",ndrs[i].cur,ndrs[i].id); else printf("%05d %d %05d\n",ndrs[i].cur,ndrs[i].id,ndrs[i].nx); // cur=ndrs[cur].nx; } } return 0; } /* 附赠一些有代表性的测试用例 00100 6 4 00000 4 99999 00100 1 12300 68288 6 -1 33218 3 00000 99999 5 68237 12309 2 33218 00100 8 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 12309 2 33218 12345 7 45678 45678 8 98765 00100 2 1 00100 1 12309 12309 2 -1 -1 1 1 00100 1 -1 00100 6 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 -1 99999 5 68237 12309 2 33218 */
AC 代码
#include<bits/stdc++.h> #include<cmath> #define mem(a,b) memset(a,b,sizeof a); #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=1e5+5; int da[maxn], nx[maxn], a[maxn]; int main() { int first,n,k,t,len; while(~scanf("%d%d%d",&first,&n,&k)) { for(int i=0;i<n;i++) { scanf("%d",&t); scanf("%d%d",&da[t],&nx[t]); } len=0; while(first!=-1) { a[len++]=first; first=nx[first]; } int times=len/k; for(int i=0,j=0; j<times; i+=k, j++) reverse(a+i,a+i+k); for(int i=0;i<len-1;i++) printf("%05d %d %05d\n",a[i],da[a[i]],a[i+1]); printf("%05d %d -1\n",a[len-1],da[a[len-1]]); } return 0; }