UVa 10148 Advertisement (贪心&标记法单个处理)

本文介绍了一种算法,用于解决如何最少地放置广告牌以确保每位慢跑者至少看到K次相同广告的问题。通过合理安排广告位置,既满足客户需求又降低成本。

10148 - Advertisement

Time limit: 3.000 seconds 

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1089

The Department of Recreation has decided that it must be more profitable, and it wants to sell advertising space along a popular jogging path at a local park. They have built a number of billboards (special signs for advertisements) along the path and have decided to sell advertising space on these billboards. Billboards are situated evenly along the jogging path, and they are given consecutive integer numbers corresponding to their order along the path. At most one advertisement can be placed on each billboard.

A particular client wishes to purchase advertising space on these billboards but needs guarantees that every jogger will see it's advertisement at leastK times while running along the path. However, different joggers run along different parts of the path.

Interviews with joggers revealed that each of them has chosen a section of the path which he/she likes to run along every day. Since advertisers care only about billboards seen by joggers, each jogger's personal path can be identified by the sequence of billboards viewed during a run. Taking into account that billboards are numbered consecutively, it is sufficient to record the first and the last billboard numbers seen by each jogger.

Unfortunately, interviews with joggers also showed that some joggers don't run far enough to seeK billboards. Some of them are in such bad shape that they get to see only one billboard (here, the first and last billboard numbers for their path will be identical). Since out-of-shape joggers won't get to seeK billboards, the client requires that they see an advertisement on every billboard along their section of the path. Although this is not as good as them seeingK advertisements, this is the best that can be done and it's enough to satisfy the client.

In order to reduce advertising costs, the client hires you to figure out how to minimize the number of billboards they need to pay for and, at the same time, satisfy stated requirements.

Input

The first line of the input consist of an integer indicating the number of test cases in theinput. Then there's a blank line and the test cases separated by a blank line.

The first line of each test case contains two integers K and N (1 ≤ KN ≤ 1000) separated by a space.K is the minimal number of advertisements that every jogger must see, andN is the total number of joggers.

The following N lines describe the path of each jogger. Each line contains two integersAi and Bi (both numbers are not greater than 10000 by absolute value).Ai represents the first billboard number seen by jogger numberi and Bi gives the last billboard number seen by that jogger. During a run, joggeri will see billboards Ai, Bi and all billboards between them.

Output

On the first line of the output fof each test case, write a single integer M. This number gives the minimal number of advertisements that should be placed on billboards in order to fulfill the client's requirements. Then writeM lines with one number on each line. These numbers give (in ascending order) the billboard numbers on which the client's advertisements should be placed. Print a blank line between test cases.

Sample input

1

5 10
1 10
20 27
0 -3
15 15
8 2
7 30
-1 -10
27 20
2 9
14 21

Sample output for the sample input

19
-5
-4
-3
-2
-1
0
4
5
6
7
8
15
18
19
20
21
25
26
27

思路:对区间右端点排序,然后从右端点开始处理每个区间,按题意模拟即可。


完整代码:

/*0.086s*/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 10000;

struct T
{
	int l, r;
	bool operator < (const T a) const
	{
		return r < a.r;///排右边
	}
} p[1005];
bool vis[N + N + 5];///这里放广告

int main()
{
	int cas, i, j, k, n, cnt, a, b, temp;
	scanf("%d", &cas);
	while (cas--)
	{
		scanf("%d%d", &k, &n);
		for (i = 0; i < n; ++i)
		{
			scanf("%d%d", &a, &b);
			if (a > b) swap(a, b);///注意
			p[i].l = N + a, p[i].r = N + b;
		}
		sort(p, p + n);
		memset(vis, 0, sizeof(vis));
		cnt = 0;
		for (i = 0; i < n; ++i)
		{
			if (p[i].r - p[i].l + 1 <= k)
			{
				for (j = p[i].l; j <= p[i].r; ++j)
					if (!vis[j]) ++cnt, vis[j] = true;///采用标记法要比直接输出更方便(因为处理多个区间很复杂,一次只研究一个区间更简单)
			}
			else
			{
				temp = k;
				for (j = p[i].l; j <= p[i].r; ++j)
					if (vis[j]) --temp;///统计广告牌数,注意可能统计成负值
				for (j = p[i].r; temp > 0; --j)
					if (!vis[j]) ++cnt, vis[j] = true, --temp;
			}
		}
		printf("%d\n", cnt);
		for (i = 0; i < N + N + 5; ++i)
			if (vis[i]) printf("%d\n", i - N);
		if (cas) putchar(10);
	}
	return 0;
}

VRRP Advertisement 是 VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)中唯一定义的一种报文类型,用于实现路由器之间的状态同步和主备切换。这种报文以组播方式发送,其目的 IP 地址为 `224.0.0.18`,目的 MAC 地址为 `01-00-5e-00-12`,IP 头部的协议号为 112 [^1]。 VRRP 路由器通过周期性地发送 Advertisement 报文来通告自己的状态,其他路由器通过监听这些报文判断当前 Master 路由器是否正常工作。默认情况下,Advertisement 报文的发送间隔为 1 秒,该值可通过 Adver Int 字段进行调整 [^3]。 在 VRRP 组中,只有处于 Master 状态的路由器才会主动发送 Advertisement 报文,而 Backup 路由器则监听这些报文以确认 Master 的状态。如果 Backup 路由器在设定的超时时间内未收到 Advertisement 报文,则会认为当前 Master 路由器发生故障,并启动选举机制,优先级更高的路由器将接替成为新的 Master,从而实现网关的高可用性 [^4]。 VRRP Advertisement 报文中包含多个关键字段,包括: - **Ver**:VRRP 版本号,v2 仅支持 IPv4,v3 支持 IPv4 和 IPv6 [^3]。 - **Virtual Rtr ID**:标识该报文关联的虚拟路由器编号。 - **Priority**:发送该报文的路由器优先级,用于选举 Master。 - **Count IP Addrs**:该报文中包含的虚拟 IP 地址数量。 - **Auth Type**:认证类型,支持不认证、明文密码和 MD5 认证。 - **Adver Int**:发送 Advertisement 报文的间隔时间。 - **IP Address(es)**:该虚拟路由器的虚拟 IP 地址。 - **Authentication Data**:认证所需的数据,如密码信息。 以下是一个简化版的 VRRP Advertisement 报文结构示意: ```c struct vrrp_advertisement { uint8_t version:4; // VRRP 版本号 uint8_t type:4; // 报文类型,固定为 Advertisement uint8_t vrid; // 虚拟路由器标识 uint8_t priority; // 路由器优先级 uint8_t count_ip_addrs; // 虚拟 IP 地址数量 uint8_t auth_type; // 认证类型 uint8_t adver_int; // 通告间隔 uint32_t checksum; // 校验和 struct in_addr ip_addrs[]; // 虚拟 IP 地址列表 }; ``` 通过这些字段,VRRP 能够实现主备路由器之间的状态同步和无缝切换,确保网络服务的连续性与稳定性 [^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值