PATA1074 Reversing Linked List(测试点1、5)

原题链接PATA1074 Reversing Linked List

本题不难,但是还是出了点小问题。
题意是,每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]还没有反转呢。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值