week10(下)

编程题#7:中位数

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 2000ms 内存限制: 65536kB

描述

中位数定义:一组数据按从小到大的顺序依次排列,处在中间位置的一个数或最中间两个数据的平均值(如果这组数的个数为奇数,则中位数为位于中间位置的那个数;如果这组数的个数为偶数,则中位数是位于中间位置的两个数的平均值).

给出一组无序整数,求出中位数,如果求最中间两个数的平均数,向下取整即可(不需要使用浮点数)

输入

该程序包含多组测试数据,每一组测试数据的第一行为N,代表该组测试数据包含的数据个数,1 <= N <= 15000.

接着N行为N个数据的输入,N=0时结束输入

输出

输出中位数,每一组测试数据输出一行

样例输入

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4
10
30
20
40
3
40
30
50
4
1
2
3
4
0

样例输出

 
 
1
2
3
25
40
2

提示

这是也一道经典的算法问题,在企业面试里出现概率很高,是“找到第K大的数”的变种。先排序再找中位数自然是很直接的做法,但排序本身很慢。我们只想找到第n/2大的数,对于其他数的顺序我们并不关心。那么怎么在不排序的前提下找到第n/2大的数呢?

#include 
    
    
     
     

using namespace std;

int main()
{
    int a[15000];
    int N,time=0;
    while(cin>>N){
      if(N!=0)
      {
        for(int i=0;i
     
     
      
      >a[i];
        }
        int middle=0;//注意变量被定义的位置
        for(int j=0;j
      
      
       
       0) large+=1;
                else if(m<0) small+=1;
            }
            if(N%2==1){
                if(small==large)
                    cout<
       
       
        
        <
        
        
       
       
      
      
     
     
    
    


编程题#8:校门外的树

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 1000ms 内存限制: 65536kB

描述

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

马路上有一些区域要用来建地铁,这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入

输入的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出

输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

样例输入

   
   
1
2
3
4
5
6
7
8
9
10
500 3
150 300
100 200
470 471
500 3
100 200
150 160
180 190

样例输出

   
   
1
2
3
4
298
400

提示

#include 
     
     
      
      

using namespace std;

int main()//大体思路是把每个区间变为没有重复不凡的几个区间;比较麻烦
{
   int a[10001];
   int l,m,x=0;
    cin>>l>>m;
    for(int i=0;i<2*m;i++)
    {
        cin>>a[i];
    }
        for(int i=0;i<2*m;i+=2)
        {
            for(int j=3;j<2*m-i;j+=2)
            {
                if(a[j-2]>a[j])//比较每个区间的右端;从小到大进行排序
                {

                    int temp1=a[j-2];
                    int temp2=a[j-3];
                    a[j-2]=a[j];
                    a[j-3]=a[j-1];
                    a[j]=temp1;
                    a[j-1]=temp2;
                }
            }
        }

        for(int i=2*m-2;i>0;i-=2)//如果每个区间的左端比上个区间的右端小
            {                    //上个区间右端的数等于这个数减1;

                if(a[i]
      
      
       
       a[i])//如果上个区间左端大于这个区间左端
                        a[i-2]=a[i];//把上个区间左端变为和这个区间左端相同

                }
            }
        for(int i=0;i<2*m;i+=2)
        {
            x+=(a[i+1]-a[i]+1);
        }
        cout<
       
       
      
      
     
     


刚才的想法,不知是否看过别人的代码才知道的这个思路;
#include 
      
      
       
       

using namespace std;

int main()//一个一个区间砍树,最后统计剩下的树的数量不会因为某区域重复被砍而改变
{
   int l,m,shu_num=0;
   cin>>l>>m;
   int shu_[l+1];
   for(int i=0;i
       
       
        
        >a>>b;
       for(int i=a;i
        
        
       
       
      
      




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值