电话 队内赛 思维问题


B.电话

有M座房子从左到右排成一条直线,每座房子有唯一的门牌号码,从1到M。这M座房子之间有一条电话线连接,现在任意2座房子之间的线路上设监听器,记录该监听器上往左或往右打电话数量。

INPUT

有多组输入,每组输入第一行是2个整数N (1 ≤ N ≤ 100 000),监听器的数量, and M (N <M ≤ 1 000 000 000), 房子的数量。接下来是N行,每行有2个数 Pi (1 ≤ Pi < M), and Ci (1 ≤ Ci ≤ 1 000 000 000), 表示由Pi监听器监听到的电话数量。Pi这个监听器只能在房子i和房子i+1之间,并且这个区域只有一个监听器。

OUTPUT

每组输出一个整数,表示该线路上最少打了多少电话。

input

output

3 4

3 1                      

2 2

1 1

2 3

1 23

2 17

3 9

7 2

8 3

3 4

2

23

5                                   

 

队内赛的一道思维问题~~蛮有意思的嘞~~就是 比赛的时候木有做出来~~ 看看 昨天晚上貌似在床上想了好久好久~~


算法~~

先排序 然后 直接找起始的最小值和最大值例如

例如 下面这个样例

3 9

7 2

8 3

3 4

先对监听器的位置进行排序从小到大

排好序后 得出来的结论是    3  4

                                         7  2

                                         8  3

然后  

需找开始的上升曲线的最大值和最小值   如图 红色点的记录为最小值min 蓝色点记录为最大值max   然后所求的值 是 所有的  (max-min)~~之和


例如 :

3 4

7 2 

8 3

  排序       4   2   3  起始点是设 min=0 ;

在前面填上两个点 就好就算初始的min  和max值了

1      0        4          2         3

    min1  max1      min2   max2

这样就好解释样例了

sum = (max1-min1)-(max2-min2)

这样就求出来了

post code:


#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;

struct node{
             int num;
             int ge;  
           }  a[101000];         
int cmp(node a , node b)
{
   return a.num<b.num;    
}

int main()
{
       int n,m,i,min,max;
       __int64 sum;       //数据量过大 用__int64来存储
       while(scanf("%d %d",&n,&m)!=EOF)
       {
          for(i=2;i<=n+1;i++)
            scanf("%d %d",&a[i].num,&a[i].ge);
          sort(a+2,a+n+2,cmp);   //排序
          a[0].ge=1;     //  添加 1  和  0 节点
          a[1].ge=0;
          a[n+2].ge=-1;   //添加  -1的节点 这样更容易判断  上升曲线的最小值和最大值
          sum=0;          
          for(i=0;i<=n+1;i++)
          {
             if( a[i].ge<=a[i+1].ge  ){    // 寻找上升曲线的最小值和最大值
                                        min=a[i].ge;
                                        max=a[i+1].ge;
                                        i++;
                                        while(a[i].ge<=a[i+1].ge  )
                                        {
                                           max=a[i+1].ge;                       
                                           i++;   
                                        }
                                        sum+=max-min;                    
                                     }                   
          }                                   
         cout<<sum<<endl;              
       }
    
}


 









评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值