Stall Reservations(POJ 3190)

本文介绍了一种解决奶牛挤奶时间冲突的算法,通过优先队列和时间排序,最小化所需挤奶位数量,确保每头奶牛在指定时间内都能单独挤奶。
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 10784 Accepted: 3813 Special Judge

Description

Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A..B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a reservation system to determine which stall each cow can be assigned for her milking time. Of course, no cow will share such a private moment with other cows. 

Help FJ by determining:

  • The minimum number of stalls required in the barn so that each cow can have her private milking period
  • An assignment of cows to these stalls over time

Many answers are correct for each test dataset; a program will grade your answer.

Input

Line 1: A single integer, N 

Lines 2..N+1: Line i+1 describes cow i's milking interval with two space-separated integers.

Output

Line 1: The minimum number of stalls the barn must have. 

Lines 2..N+1: Line i+1 describes the stall to which cow i will be assigned for her milking period.

Sample Input

5
1 10
2 4
3 6
5 8
4 7

Sample Output

4
1
2
3
2
4

解题思路:

奶牛到挤奶的时间就必须要挤,只需逐个观察该奶牛需要挤奶时,有没有空牛棚即可。

1)把所有奶牛根据开始时间从小到大进行排序。

2)为第一头奶牛分配一个牛棚。

3)依次对后面的奶牛进行操作,处理第 i 头时,考虑这时有没有空牛棚(上一只奶牛挤奶结束)。

     令结束时间最早的牛棚结束时间为E(x)(奶牛挤奶结束时间),S(i)为第i头奶牛开始的时间

    如果E(x) < S(i) 则不用新增牛棚,i 可以进入 x,并修改E(i)。

    如果E(x) >= S(i) 则需要新增牛棚,并使该牛棚的结束事假为E(i)。

在为牛分配牛棚时存在三种情况

1)还没有建造过牛棚,此时就要新增牛棚,并把牛棚结束时间改为第一头牛的E(i)。

2)建过牛棚,该牛可以进入最早结束的牛棚进行操作。

3)建过牛棚,但是最早结束的牛棚的结束时间 >= 该牛的开始时间,则要新增牛棚。

注意:优先队列默认为从大到小排列,如果要从小到大,排列规则的符号与一般的相反(> 改成 <)

代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct cow {
    int a,b;
    int nu;   //牛的编号
    bool operator < (const cow & c) const{
        return a < c.a;
    }
}cows[50000+10];
int pos [50000+10]; //pos[i]表示编号为i的牛去的牛棚
struct stall{
    int end;
    int nu;
    bool operator <(const stall & c) const{
        return end > c.end;
    }
    stall(int x,int y):end(x),nu(y){ }
};
int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 0;i < n;i++){
        scanf("%d %d",&cows[i].a,&cows[i].b);
        cows[i].nu = i;
    }
    sort(cows,cows+n);
    int total = 0;
    priority_queue<stall> pq;
    for(int i = 0;i < n;i++){
        if(pq.empty()){
            total++;
            pq.push (stall(cows[i].b,total));
            pos[cows[i].nu] = total;
        }
        else{
            stall st = pq.top();
            if(st.end < cows[i].a){
                pq.pop();
                pos[cows[i].nu] = st.nu;
                pq.push (stall(cows[i].b,st.nu));
            }
            else{
                total++;
                pos[cows[i].nu] = total;
                pq.push (stall(cows[i].b,total));
            }
        }
    }
    printf("%d\n",total);
    for(int i = 0;i < n;i++){
        printf("%d\n",pos[i]);
    }
    return 0;
}

 

### RCU Stall 的概念及其处理 RCU(Read-Copy Update)是一种用于多线程环境下的同步机制,在 Linux 内核中被广泛使用。当发生 RCU stall 时,意味着某个 CPU 或者任务长时间处于一种状态,阻止了 RCU grace period 的完成[^1]。 #### RCU Stall 的检测流程 在内核中,`rcu_sched_clock_irq()` 是触发 RCU stall 检测的一个重要函数。它通过调用一系列子函数来确认是否存在 stalled CPUs 并打印相关信息。以下是其主要路径: - `rcu_sched_clock_irq()` 调用了 `rcu_pending()` 来检查是否有未决的 RCU 工作项。 - 如果存在未决工作,则进一步调用 `check_cpu_stall()` 进行更详细的分析。 - 当发现确实存在 stalled CPUs 时,会依次调用 `print_cpu_stall()` 和其他辅助函数(如 `rcu_dump_cpu_stacks()`、`dump_cpu_task()` 等),最终生成堆栈回溯信息以便调试[^2]。 #### 处理策略 针对 RCU stall 的情况,可以通过调整内核参数来进行控制。例如,`sysctl_panic_on_rcu_stall` 参数决定了系统是否应在检测到 RCU stall 后立即崩溃并记录日志。如果该值设置为 true (`1`) ,那么一旦检测到 stall 将直接引发 kernel panic,并显示 “RCU Stall” 错误消息。 另外需要注意的是,尽管上述讨论集中在 RCU stalls 上,但在现代操作系统中有许多类似的性能瓶颈现象可以利用 Pressure Stall Information (PSI) 技术监测。PSI 提供了一种方法用来衡量由于资源竞争而导致的任务延迟程度,并且能够持续一段时间维持活跃状态以减少波动影响[^3]。 对于您提到的关于 ID 级寄存器 rs1 和 rs2 修改选项部分,这似乎涉及到了指令流水线设计中的数据前馈问题以及如何选择合适的数据源作为操作数输入给后续阶段使用的问题[^4]。不过这部分内容与前面所描述的 RCU stall 主题关联不大。 ```c // 示例代码展示如何启用 sysctl_panic_on_rcu_stall 参数 #include <linux/sysctl.h> static struct ctl_table rcu_sysctls[] = { { .procname = "panic_on_rcu_stall", .data = &sysctl_panic_on_rcu_stall, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值