HDU 6215 链表

题意:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6215
给出n个数的序列,每一轮需要删除当前这一轮比左边的数小或者比右边的数大的数字,然后再将剩下的部分合并,进行下一轮。最后序列变成非递减时结束,输出最后序列。


思路:

很显然每一轮就删掉一段递减的序列,比如,{1,2,3,7,6,5,8}删除的就是7,6,5,可以发现,每次删除一段后只会对这一段左右两边的数字有影响。
采用链表维护,每次删除后将左右两边的链表的合并起来,为了避免对已经正确排序的数字产生大量的重复扫描,所以在新一轮的待排序的head数组中只存放前一轮的删除段左边的第一个数字,比如上述例子新数组只存放3,然后每次从head数组开始扫描,找到递减段,删除后再次更新head数组即可。
详见代码。


代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;

int a[MAXN], nxt[MAXN], last[MAXN], head[MAXN];

int main() {
    //freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, s = 0, t = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            nxt[i] = i + 1;
            last[i] = i - 1;
            head[t++] = i;
        }
        a[0] = 0; nxt[0] = 1; last[n + 1] = n;
        int ans = n, flag = 1;
        while (flag) {
            int x = 0, s = 0;
            flag = 0;
            while (x < t) {
                int now = head[x], cnt = 0;
                while (nxt[now] <= n && a[now] > a[nxt[now]]) {
                    now = nxt[now]; ++cnt; flag = 1;
                }
                if (cnt) {
                    ans -= (cnt + 1);
                    nxt[last[head[x]]] = nxt[now];
                    last[nxt[now]] = last[head[x]];
                    head[s++] = last[head[x]];
                }
                while (head[x] <= now && x < t) ++x;
            }
            t = s;
        }
        printf("%d\n", ans);
        int x = 0;
        while (x <= n) {
            if (x != 0) printf("%d ", a[x]);
            x = nxt[x];
        }
        printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值