第一题:染色问题(NOIP2009模拟测试题)

染色问题 

问题描述:

有一段从0到1000000000的数轴,它开始的颜色是白色。现在有人不断把其中的一段染成黑色或白色,总共染了N段(1<=N<=5000)。你的任务是编写一个程序,找出最后最长的白色段。

输入:第一行只有一个数N,接下来的N行是每次染一段的信息,格式为:ai bi ci。

ai、bi是整数,ci是符号’b’或’w’,三者用空格隔开,表示这次从ai染到bi,用的颜色为ci(’w’表示白色,’b’表示黑色),你可以认为0<ai<=bi<1000000000。

输出:仅两个数x,y(x<=y),用空格隔开,表示最长的白色段。如果有多个解,则输出X最小的解。

〖输入输出样例〗:

dye.in

dye.out

4

1 999999997 b

40 300 w

300 634 w

43 47 b

 

48 634

 

/******************************************************************************************************
 ** Copyright (C) 2011.07.01-2013.07.01
 ** Author: famousDT <13730828587@163.com>
 ** Edit date: 2011-10-17
******************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>//abs,atof(string to float),atoi,atol,atoll
#include <math.h>//atan,acos,asin,atan2(a,b)(a/b atan),ceil,floor,cos,exp(x)(e^x),fabs,log(for E),log10
#include <vector>
#include <queue>
#include <map>
#include <time.h>
#include <set>
#include <list>
#include <stack>
#include <string>
#include <iostream>
#include <assert.h>
#include <string.h>//memcpy(to,from,count
#include <ctype.h>//character process:isalpha,isdigit,islower,tolower,isblank,iscntrl,isprll
#include <algorithm>
using namespace std;

//typedef long long ll;

#define MY_PI acos(-1)
#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))
#define MY_MALLOC(n, type) ((type *)malloc((n) * sizeof(type)))
#define MY_ABS(a) (((a) >= 0) ? (a) : (-(a)))
#define MY_INT_MAX 0x7fffffff

/*==========================================================*\
| noip
\*==========================================================*/
struct segment
{
    int low;
    int high;
} seg[100005], tmp[100005];
bool cmp(segment a, segment b)
{
    return a.low < b.low;
}
int main()
{
    FILE *in, *out;
    in = freopen("dye.in", "r", stdin);
    out = freopen("dye.out", "w", stdout);
	int n;
	int i, j, k, a, b;
	int index = 1;
	char c;
	scanf("%d", &n);
	seg[0].low = 0;
	seg[0].high = 1000000000;
	for (k = 0; k < n; ++k) {
		scanf("%d%d %c", &a, &b, &c);
		if (c == 'w') {//合并白色区间,可以用二分
			int pos = 0;
			seg[index].low = a;
			seg[index].high = b;
			++index;
			sort(seg, seg + index, cmp);
			int t_low = seg[0].low;
			int t_high = seg[0].high;
			for (i = 0; i < index; ++i) {
				if (seg[i].low <= t_high) {
					if (seg[i].high > t_high) {
						t_high = seg[i].high;
					}
				} else {
					seg[pos].low = t_low;
					seg[pos++].high = t_high;
					t_low = seg[i].low;
					t_high = seg[i].high;
				}
			}
			seg[pos].low = t_low;
			seg[pos++].high = t_high;
			index = pos;
        } else {//白色区间减去黑色区间,分情况讨论
			int pos = 0;
			for (i = 0; i < index; ++i) {
				if (seg[i].high < a || seg[i].low > b) {
					tmp[pos].low = seg[i].low;
					tmp[pos].high = seg[i].high;
					++pos;
				} else if (seg[i].low >= a && seg[i].high <= b) {
					;
				} else if (seg[i].low >= a && seg[i].high > b) {
					tmp[pos].low = b + 1;
					tmp[pos].high = seg[i].high;
					++pos;
				} else if (seg[i].low < a && seg[i].high <= b) {
					tmp[pos].low = seg[i].low;
					tmp[pos].high = a - 1;
					++pos;
				} else if (seg[i].low < a && seg[i].high > b) {
					tmp[pos].low = seg[i].low;
					tmp[pos].high = a - 1;
					++pos;
					tmp[pos].low = b + 1;
					tmp[pos].high = seg[i].high;
					++pos;
				}
			}
			for (i = 0; i < pos; ++i) {
				seg[i].low = tmp[i].low;
				seg[i].high = tmp[i].high;
			}
			index = pos;
		}		
    }
	int max = -1;
	int ans;
	for (i = 0; i < index; ++i) {
		int t = seg[i].high - seg[i].low;
		if (t > max) {
			max = t;
			ans = i;
		}
	}
	printf("%d %d\n", seg[ans].low, seg[ans].high);
	system("pause");
	return 0;
}
/*
4
1 999999997 b
40 300 w
300 634 w
43 47 b
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值