• hdu4302 set或者线段树


    题意:
          一条蛇生活在一个管子里,然后管子上面的某些位置会一次出现食物,每次蛇都会吃最近的食物,吃完之后就原地不动,等待下一次吃食物,如果有两个食物距离蛇一样远并且都是最近的,那么蛇不会掉头,而是直接按他最后停留的方向走,去吃自己前方的食物,最后给一些命令,问蛇一共走了多少路。

    思路:

          看完一下就想到了set,结果果断用set过了,后来听说这个题目可以用线段树来做,自己想了下,用线段树也不是很难,结果又写了个线段树,也AC了,set用时359ms,线段树用了515ms,无论是哪个方法,这个题目就是要迅速的找到比当前值大的最小的那个数,和比当前值小的最大的那个数(或者当前值本身),如果是找大于等于的第一个数在set里可以直接 *my_set.lower_bound(now);,如果是小于等于也用同样的方法,只不过是吧所有的数都存成负数就行了,对于线段树也比较好写,每个节点有两个权值,一个是当前区间的最大值,一个是最小值,然后就是简单的更新和查找了,要有一个就是这个题目同一个点可能同时存在多个食物,所以开个数组记录每个节点的食物个数,吃了就--,如果是0就直接删除就行了,具体的看代码。


    SET 359ms

    #include<stdio.h>
    #include<set>
    
    #define INF 1000000000
    
    using namespace std;
    
    set<int>low ,up;
    int num[110000];
    
    int abss(int x)
    {
        return x < 0 ? -x : x;
    }
    
    int main ()
    {
        int t ,n ,m;
        int a ,b ,cas = 1;
        scanf("%d" ,&t);
        while(t--)
        {
           scanf("%d %d" ,&n ,&m);
           low.clear() ,up.clear();
           memset(num ,0 ,sizeof(num));
           up.insert(INF);
           low.insert(INF);
           int now = 0;
           int sum = 0;
           int fx = 1;
           while(m--)
           {
              scanf("%d" ,&a);
              if(!a)
              {
                  scanf("%d" ,&b);
                  up.insert(b);
                  low.insert(-b);
                  num[b] ++;
              }
              else 
              {
                 a = *up.lower_bound(now);
                 b = *low.lower_bound(-now);
                 if(b != INF) b = -b;
                 if(a == INF && b == INF) continue;
                 if(!abss(a - now)) 
                 {
                     if(!--num[a])
                     up.erase(a) ,low.erase(-a);
                     continue;
                 }
                 if(!abss(b - now))
                 {
                     if(!--num[b])
                     up.erase(b) ,low.erase(-b);
                     continue;
                 }   
                
                 if(abss(a - now) < abss(b - now))
                 {
                    sum += abss(a - now);
                    if(now < a) fx = 1;
                    else fx = 2;
                    now = a;
                   if(!--num[a])
                   up.erase(a) ,low.erase(-a);
                 }
                 else if(abss(a - now) > abss(b - now))
                 {
                    sum += abss(b - now);
                    if(now < b) fx = 1;
                    else fx = 2;
                    now = b;
                    if(!--num[b])
                    up.erase(b) ,low.erase(-b);
                 }
                 else 
                 {
                     sum += abss(a - now);
                     if(fx == 1 && now < a || fx == 2 && now > a)
                     {
                         now = a;
                         if(!--num[a])
                         up.erase(a) ,low.erase(-a);
                     }
                     else 
                     {
                         now = b;
                        if(!--num[b])
                        up.erase(b) ,low.erase(-b);
                         
                     }
                 }
              }
           }
           printf("Case %d: %d
    " ,cas ++ ,sum);
        }
        return 0;
    }
    
    
    字典树 515ms
    #include<stdio.h>
    #include<string.h>
    
    #define lson l ,mid ,t << 1
    #define rson mid + 1 ,r ,t << 1 | 1
    #define INF 100000000
    
    int max[440000] ,min[440000];
    int num[110000];
    
    int maxx(int x ,int y)
    {
        return x > y ? x : y;
    }
    
    int minn(int x ,int y)
    {
        return x < y ? x : y;
    }
    
    int abss(int x)
    {
        return x < 0 ? -x : x;
    }
    
    void Pushup(int t)
    {
         max[t] = maxx(max[t<<1] ,max[t<<1|1]);
         min[t] = minn(min[t<<1] ,min[t<<1|1]);
         return ;
    }
    
    void BuidTree(int n)
    {
         for(int i = 1 ;i <= n * 4 ;i ++)
         max[i] = -INF ,min[i] = INF;
         memset(num ,0 ,sizeof(num));
         return;
    }
    
    void Update(int l ,int r ,int t ,int a ,int b ,int c)
    {
         if(l == r)
         {
              max[t] = b ,min[t] = c;
              return ;
         }
         int mid = (l + r) >> 1;
         if(a <= mid) Update(lson ,a ,b ,c);
         else Update(rson ,a ,b ,c);
         Pushup(t);
         return ;
    }
    
    int Query_max(int l ,int r ,int t ,int a ,int b)
    {
         if(a <= l && b >= r)
         return max[t];
         int mid = (l + r) >> 1;
         int ans = 0;
         if(a <= mid) ans = Query_max(lson ,a ,b);
         if(b > mid) ans = maxx(ans ,Query_max(rson ,a ,b));
         return ans;
    }
    
    int Query_min(int l ,int r ,int t ,int a ,int b)
    {
        if(a <= l && b >= r)
        return min[t];
        int mid = (l + r) >> 1;
        int ans = INF;
        if(a <= mid) ans = Query_min(lson ,a ,b);
        if(b > mid) ans = minn(ans ,Query_min(rson ,a ,b));   
        return ans;
    }
    
    int main ()
    {
        int t ,m ,n ,i ,a ,b ,sum ,now ,fx ,cas = 1;
        scanf("%d" ,&t);
        while(t--)
        {
           scanf("%d %d" ,&n ,&m);
           n++ ,now = 1 ,sum = 0 ,fx = 1;
           BuidTree(n);
           while(m--)
           {
               scanf("%d" ,&a);
               if(!a)
               {
                   scanf("%d" ,&b);
                   num[++b] ++;
                   if(num[b] == 1) 
                   Update(1 ,n ,1 ,b ,b ,b);
                   continue;
               }
               
               if(num[now])
               {
                   sum += 0;
                   if(!--num[now])
                   Update(1 ,n ,1 ,now ,-INF ,INF);
                   continue;
               }
     
               if(now == 1) a = -INF;
               else a = Query_max(1 ,n ,1 ,1 ,now - 1);
               if(now == n) b = INF;
               else b = Query_min(1 ,n ,1 ,now + 1 ,n);
               if(a == -INF && b == INF) continue;
               
               if(abss(a - now) < abss(b - now))
               {
                   sum += abss(a - now);
                   fx = a < now ?  1 :  2;
                   now = a;
                   if(!--num[now])
                   Update(1 ,n ,1 ,now ,-INF ,INF);
               }
               else if(abss(a - now) > abss(b - now))
               {
                   sum += abss(b - now);
                   fx = b < now ?  1 :  2;
                   now = b;
                   if(!--num[now])
                   Update(1 ,n ,1 ,now ,-INF ,INF);
               }
               else 
               {
                   sum += abss(a - now);
                   if(fx == 1 && a < now || fx == 2 && a > now)
                   {
                       now = a;
                       if(!--num[now])
                       Update(1 ,n ,1 ,now ,-INF ,INF);       
                   }
                   else 
                   {
                       now = b;
                       if(!--num[now])
                       Update(1 ,n ,1 ,now ,-INF ,INF);
                   }
               }
          }
          printf("Case %d: %d
    " ,cas ++ ,sum);
       }
       return 0;
     }
                   
                   
                   


  • 相关阅读:
    提示框第三方库之MBProgressHUD
    三种ViewController跳转的异同
    性能测试学习第一天_性能测试常见术语
    JSONArray与list互转
    web service CXF工作中使用总结
    局部变量、类变量、实例变量有什么区别
    hibernate 的几种查询——工作中使用到的
    tomcat 常见启动问题小记
    文本编辑器KindEditor的使用
    kaptcha Java验证码
  • 原文地址:https://www.cnblogs.com/csnd/p/12062832.html
Copyright © 2020-2023  润新知