Ural 1019 Line Painting

点击打开链接ural 1019

思路:离散化
分析:
1 这一题的区间的最大值为10^9而n最大为5000,很明显就是利用离散化
2 题目中说了区间[0,10^9]刚开始为白色,而给定重刷的区间的值是大于0小于10^9的,所以我们应该开始就要考虑到0和10^9.
3 然后我们应该注意这题是对线段染色,所以我们应该要注意在处理的时候应该要把这些区间看成点来处理,然后会有两种方法分别是暴力和线段树

代码

线段树

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 10010;
struct Node{
    int left;
    int right;
    int mark;
    char color;
};
Node node[4*MAXN] , tmp[MAXN];
int n , pos;
int num[MAXN];

//二分查找
int search(int x){
    int left , right;
    left = 1 , right = pos-1;
    while(left <= right){
        int mid = (left + right)>>1;
        if(num[mid] == x)
           return mid;
        else if(num[mid] > x)
           right = mid-1;
        else
           left = mid+1;
    }
}

//建立线段树
void buildTree(int left , int right , int pos){
    node[pos].left = left;
    node[pos].right = right;
    node[pos].mark = 0;
    if(left == right)
      return;
    int mid = (left+right)>>1;
    buildTree(left , mid , pos<<1);
    buildTree(mid+1 , right , (pos<<1)+1);
}

//向下更新
void push_down(int pos){
    if(node[pos].mark != -1){
       node[pos<<1].mark = node[(pos<<1)+1].mark = node[pos].mark;
       node[pos].mark = -1;
    }
}

//更新
void update(int left , int right , int value , int pos){
    if(left <= node[pos].left && right >= node[pos].right){
       node[pos].mark = value;
       return;
    }
    push_down(pos);
    int mid = (node[pos].left + node[pos].right)>>1;
    if(right <= mid)
      update(left , right , value , pos<<1);
    else if(left > mid)
      update(left , right , value , (pos<<1)+1);
    else{
      update(left , mid , value , pos<<1);
      update(mid+1 , right , value , (pos<<1)+1);
    }
}

//询问
int query(int index , int pos){
    if(node[pos].left == node[pos].right)
       return node[pos].mark;
    push_down(pos);
    int mid = (node[pos].left + node[pos].right)>>1;
    if(index <= mid)
       return query(index , pos<<1);
    else
       return query(index , (pos<<1)+1);
}

int main(){
    while(scanf("%d" , &n) != EOF){
        pos = 1;
        num[pos++] = 0;
        num[pos++] = 1e9;
        for(int i = 0 ; i < n ; i++){
           scanf("%d %d %c" , &tmp[i].left , &tmp[i].right , &tmp[i].color);
           num[pos++] = tmp[i].left;
           num[pos++] = tmp[i].right;
        }
        sort(num+1 , num+pos);
        pos = unique(num+1 , num+pos)-num;
        //离散化
        for(int i = 0 ; i < n ; i++){
           tmp[i].left = search(tmp[i].left);
           tmp[i].right = search(tmp[i].right);
        }
        buildTree(1 , pos-1 , 1);
        //更新
        for(int i = 0 ; i < n ; i++){
           int value = 0;
           if(tmp[i].color == 'b')
              value = 1;
           update(tmp[i].left , tmp[i].right-1 , value , 1);
        }
        //求解最长的白色区间
        int left , right;
        left = right = 0;
        for(int i = 1 ; i < pos-1 ; i++){
           if(!query(i , 1)){
              int j = i+1;
              while(j < pos-1 && !query(j , 1))
                   j++;
              int dis = num[j]-num[i];
              if(dis > right-left){
                 left = num[i];
                 right = num[j];
              }
              i = j;
           }
        }
        printf("%d %d\n" , left , right);
    }
    return 0;
}

暴力

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 100010;
struct Node{
    int left;
    int right;
    int mark;
    char color;
};
Node node[MAXN];
int vis[MAXN];
int num[MAXN];
int pos;

//二分查找
int search(int x){
    int left = 1 , right = pos-1;
    while(left <= right){
        int mid = (left+right)>>1;
        if(num[mid] == x)
          return mid;
        else if(num[mid] > x)
          right = mid-1;
        else
          left = mid+1;
    }
}

int main(){
    int n;
    while(scanf("%d" , &n) != EOF){
        pos = 1;
        num[pos++] = 0;
        num[pos++] = 1e9;
        for(int i = 0 ; i < n ; i++){
            scanf("%d %d %c" , &node[i].left , &node[i].right , &node[i].color);
            num[pos++] = node[i].left;
            num[pos++] = node[i].right;
        }
        sort(num+1 , num+pos);
        pos = unique(num+1 , num+pos)-num;
        for(int i = 0 ; i < n ; i++){
           node[i].left = search(node[i].left);
           node[i].right = search(node[i].right);
        }
        //染色
        memset(vis , 0 , sizeof(vis));
        for(int i = 0 ; i < n ; i++){
            int value = 0;
            if(node[i].color == 'b')
              value = 1;
            for(int j = node[i].left ; j < node[i].right ; j++)
              vis[j] = value;
        }
        int left , right;
        left = right = 0;
        //找最大的连续的白色区间
        for(int i = 1 ; i < pos-1 ; i++){
           if(!vis[i]){
             int j = i+1;
             while(j < pos-1 && !vis[j])
                  j++;
             int dis = num[j]-num[i];
             if(dis > right-left){
                right = num[j];
                left = num[i];
             }
             i = j;
           }
        }
        printf("%d %d\n" , left , right);
    }
    return 0;
}
时间: 2024-10-31 17:00:40

Ural 1019 Line Painting的相关文章

UVa 253 Cube painting (模拟)

253 - Cube painting Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=99&page=show_problem&problem=189 We have a machine for painting cubes. It is supplied with three different colors:

POJ 2606 / URAL 1502 Rabbit hunt:计算几何

1052. Rabbit Hunt http://poj.org/problem?id=2606 http://acm.timus.ru/problem.aspx?space=1&num=1052 Time limit: 1.0 second Memory limit: 64 MB A good hunter kills two rabbits with one shot. Of course, it can be easily done since for any two points we

UVa 10706 / POJ 1019 Number Sequence:打表及O(1)算法

10706 - Number Sequence Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=19&page=show_problem&problem=1647 http://poj.org/problem?id=1019 Description A single positive integer i is giv

cache line填充后运行时间问题

问题描述 cache line填充后运行时间问题 #include #include int main(int argc,char* argv[]) { int len = 64*1024*1024; int K =atoi(argv[1]); int arr = (int)malloc(sizeof(int)*len); int i; for(i=0;i<len;i+=K) { arr[i]*=3; } return 0; } 按照http://blog.csdn.net/cool_way/a

Binary XML file line #2: Error inflating

06-27 14:29:27.600: E/AndroidRuntime(6936): FATAL EXCEPTION: main   06-27 14:29:27.600: E/AndroidRuntime(6936): android.view.InflateException: Binary XML file line #2: Error inflating class       com.example.FileListItem   06-27 14:29:27.600: E/Andro

Line 属性

  只读属性,返回 TextStream 文件中当前的行号. object.Line object 总是 TextStream 对象的名称. 说明 在文件初始打开并写入任何字符之前,Line 等于 1. 下面的示例演示了Line 属性的用法: function GetLine(){   var fso, f, r   var ForReading = 1, ForWriting = 2;   fso = new ActiveXObject("Scripting.FileSystemObject&

分享关于Line Phone概念手机的设计心得

文章描述:Line Phone概念手机的设计感悟. 文/田飞 湖南工业大学青年教师田飞设计的Line Phone概念手机是2011年芙蓉杯国际工业设计大赛"数字产品与服务设计类"金奖获奖作品.Line Phone概念手机完美结合了中国风和科技元素,部分资料(主要是指视频)在优酷上公布后,令人大为惊艳,并引起了设计.消费电子.互联网界的广泛关注,本文中,田飞将和大家分享关于Line Phone的设计心得. 更简单的使用 智能机的发展使手机的功能越来越强大,与此同时,其复杂性也不断增加,很

VB6.0自制Line控件时实现X1,Y1,X2,Y2属性

控件 Line控件本来是最简单的一个控件,但它太简单了,以至于不提供我们想要的一些事件,为了增强它的功能,我自己制作了一个Line控件,还 给她取名叫作MLine控件. 制作控件的方法请参看"MSDN - Visual Basic 文档 - 使用Visual Basic -部件工具指南 - 创建ActiveX部件"中的"创建一个ActiveX控件"和" 建立ActiveX控件"部分. VB自带的Line控件有X1,X2,Y1,Y2四个属性,没有L

Ural

Let's consider K-based numbers, containing exactly N digits. We define a number to be valid if itsK-based notation doesn't contain two successive zeros. For example: 1010230 is a valid 7-digit number; 1000198 is not a valid number; 0001235 is not a 7