本题不难,但是还是出了点小问题。
题意是,每k个反转,最后不足k个,保持原样
原来代码是
#include <bits/stdc++.h>
using namespace std;
struct Node{
int r;
int data,address,nextaddress;
Node():r(1000000){}
bool operator < (const Node &b) const{
return r < b.r;
}
}node[100010];
int main()
{
int n,k,st;
scanf("%d%d%d",&st,&n,&k);
for(int i = 0;i < n;i++){
int add;
scanf("%d",&add);
node[add].address = add;
scanf("%d%d",&node[add].data,&node[add].nextaddress);
}
int cnt = 0,r = 1;
while(st != -1){
node[st].r = r++;
st = node[st].nextaddress;
cnt++;
}
sort(node,node+100010);
for(int i = 0;i < cnt; ){//注意,这里不让i自增
int j = i;
while(j < cnt && j - i + 1 <= k) j++;//从i开始往后找k个元素,不够k个则到最后一个结束
if(j - i == k) reverse(node+i,node+j);//检测一下当前[i,j)区间是否够了k个,够则反转
for(int cur = i;cur < j;cur++){//输出当前区间[i,j)中的元素
printf("%05d %d ",node[cur].address,node[cur].data);
if(cur == cnt - 1) printf("-1");//下一个结点的地址根据是否是最后一个结点来特判
else printf("%05d\n",node[cur+1].address);
}
i = j;
}
for(int i = 0;i < cnt;i++){
if(i != cnt - 1)
printf("%05d %d %05d\n",node[i].address,node[i].data,node[i+1].address);
else printf("%05d %d -1",node[i].address,node[i].data);
}
return 0;
}
这份代码过不去测试点1、5,但是其余的测试点都可以通过,也就是说明,思路没有问题,但是有细节没有处理好。一直想不出有什么问题,于是,将反转与打印单独分离出来。
#include <bits/stdc++.h>
using namespace std;
struct Node{
int r;
int data,address,nextaddress;
Node():r(1000000){}
bool operator < (const Node &b) const{
return r < b.r;
}
}node[100010];
int main()
{
int n,k,st;
scanf("%d%d%d",&st,&n,&k);
for(int i = 0;i < n;i++){
int add;
scanf("%d",&add);
node[add].address = add;
scanf("%d%d",&node[add].data,&node[add].nextaddress);
}
int cnt = 0,r = 1;
while(st != -1){
node[st].r = r++;
st = node[st].nextaddress;
cnt++;
}
sort(node,node+100010);
//必须先反转,再输出,不可以翻转一块,输出一块
for(int i = 0;i < cnt; ){
int j = i;
while(j < cnt && j - i + 1 <= k) j++;
if(j - i == k) reverse(node+i,node+j);
i = j;
}
for(int i = 0;i < cnt;i++){
if(i != cnt - 1)
printf("%05d %d %05d\n",node[i].address,node[i].data,node[i+1].address);
else printf("%05d %d -1",node[i].address,node[i].data);
}
return 0;
}
这样通过了测试点1、5。
思考了一下。其实不能将反转区间与打印在一起进行。因为,比如说一共有10个有效结点,即cnt = 10,而k等于4。
结点地址为0,1,2,3,4,5,6,7,8,9。
则一开始的代码实现是先将[0,4)反转为[3,2,1,0],然后打印,问题就出在打印上,此时,当cur为0时,其后面还有结点,应该打印的是7,而不是4,应该整体完全按照要求反转之后再打印,否则,此时下一节,即[4,5,6,7]还没有反转呢。