回 帖 发 新 帖 刷新版面

主题:[讨论]第76次编程比赛结果讨论

比赛贴已经结了!

至于结果,还没出来,我会尽快的.

我把题目贴过来,大家可以讨论讨论

一、过河问题

问题描述:
     在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是S到T之间的任意正整数(包括S,T)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。

题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

输入:
  第一行有一个正整数L(1 <= L <=10^9),表示独木桥的长度。第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1 <= S <= T <= 10,1 <= M <= 100。第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。

输出:

只包括一个整数,表示青蛙过河最少需要踩到的石子数。

样例输入:
10
2 3 5
2 3 5 6 7

样例输出:

2

二、南极冰山问题

   传说中,南极有一片广阔的冰原,在冰原下藏有史前文明的遗址。整个冰原被横竖划分成了很多个大小相等的方格。在这个冰原上有N个大小不等的矩形冰山,这些巨大的冰山有着和南极一样古老的历史,每个矩形冰山至少占据一个方格,且其必定完整地占据方格。冰山和冰山之间不会重叠,也不会有边或点相连。
ACM探险队在经过多年准备之后决定在这个冰原上寻找遗址。根据他们掌握的资料,在这个冰原上一个大小为一格的深洞中,藏有一个由史前人类制作的开关。而唯一可以打开这个开关的是一个占据接近一格的可移动的小冰块。显然,在南极是不可能有这样小的独立冰块的,所以这块冰块也一定是史前文明的产物。他们在想办法把这个冰块推到洞里去,这样就可以打开一条通往冰原底部的通道,发掘史前文明的秘密。冰块的起始位置与深洞的位置均不和任何冰山相邻。
这个冰原上的冰面和冰山都是完全光滑的,轻轻的推动冰块就可以使这个冰块向前滑行,直到撞到一座冰山就在它的边上停下来。冰块可以穿过冰面上所有没有冰山的区域,也可以从两座冰山之间穿过。冰块只能沿网格方向推动。
 
输入 
   输入文件第一行为冰山的个数N (1<=N<=4000),第二行为冰块开始所在的方格坐标X1,Y1,第三行为深洞所在的方格坐标X2,Y2,以下N行每行有四个数,分别是每个冰山所占的格子左上角和右下角坐标Xi1,Yi1,Xi2,Yi2 (坐标都在int 型范围内即 -2^31到2^31)
 
输出
   输出文件仅包含一个整数,为最少推动冰块的次数。如果无法将冰块推入深洞中,则输出0。
 
样例输入 
   2
1 1
5 5
1 3 3 3
6 2 8 4
 
样例输出 
   3



另外,我没找到测试数据,谁有可以贴上来
如果没有,只能自己做几个,比较少

回复列表 (共17个回复)

沙发

自己做的测试数据,很少,不全面,大家可以自己试试,


过河问题:

测试1:   // 原题题目给出的,估计都过了
10
2 3 5
2 3 5 6 7

结果:

2

*********************

测试2:
100000000     // 把数写大,测试一下算法效率
2 3 10
2 3 45 56 678 3456 5678 6789 45678 345678

结果:

1

********************

测试3:     // 这个算法不好的,要8、9秒以上,好的瞬间出
100000000
2 3 10
2 3 5 6 7 100 5678 6789 45678 345678

结果:
2


测试4:   //  测试是否对石子排序
10
2 3 5
7 6 2 3 5

结果:
3





***************************************************************

***************************************************************

冰山问题;

测试1:   // 原题目已给出

2
1 1 
5 5
1 3 3 3
6 2 8 4

结果:

3

**********************

测试2:   //  测试坐标范围是否全面
5
1 -1
-2 1
2 -1 2 0
-1 -3 1 -3
-4 -3 -4 -1
-4 3 -2 3
3 2 3 3


结果;
5

********************

测试3:    // 不可达到目标,输出0,我贴上的程序,没有按要求,我是输出的Error!!!
1
1 1
5 5
1 3 3 3

结果:
0         

*******************

测试4:   // 测试极端情况
2
1 -1
-2 1
-100000001 -2 -100000000 -1
-100000001 100000000 -99999999,100000001

结果:
0

板凳

之前的不知道怎么答案为5的那个出不来。。。今天修改了一些地方的坐标影射方式,又好了。

3 楼

难道LZ是手工测的吗?

4 楼


呵呵,是的。

提交的代码,一般都没有全部通过的,虽然就这几组

我还要在研究研究在飞燕onlinejudge上下的那个测试系统,还没搞定,试了几次都不行

5 楼


   不好意思啊,我这个菜鸟想提一点小要求,就是请各位高手给出代码时可否略作一些
注释呢?否则对于我这样的新而又真心想学的人来说,理解有些困难,拜托了。
    不好意思加谢谢。

6 楼

样例输入:
10
2 3 5
2 3 5 6 7

样例输出:

2

这样计算第一次0跳到去3,再3跳去6,再跳也去不到10啊????是不是有点问题解释一下还是我理解错??

7 楼

ls没有看清题目啊

输出的是最少踩到的石子数,不是几次跳过去

这是我写的程序,现在贴上来吧,不知道对不对

#include <iostream>
using namespace std;

int F_min(int* dp,int D_min,int D_max)
{
    int min=0x7fffffff;
    for(int i=D_min;i<=D_max;i++)
    {
        min=min<dp[i]?min:dp[i];
    }
    return min;

}

int main()

    int L_bridge,D_min,D_max,S_num;
    int *dp;   // 窗口数组
    int *Bridge;
    int Menkan;
    int Min;

    //  输入数据————————————————————————————    
    cout<<"请输入桥的长度L_bridge:"<<endl;
    cin>>L_bridge;
    cout<<"请输入跳跃的最小距离D_min、跳跃的最大距离D_max、石子的个数S_num:"<<endl;
    cin>>D_min>>D_max>>S_num;
    
    //开辟空间—————————————————————————————
    Bridge=new int[S_num];
    for(int i=0;i<S_num;i++) 
        cin>>Bridge[i];
    
    //D_min , D_max相等的情况——————————————————————
    if(D_min==D_max)
    {
        int counter=0;
        for(i=0;i<S_num;i++) 
            if(Bridge[i]%D_min==0)
                counter++;
        cout<<"最少踩到的石子数为:"<<endl;
        cout<<counter;
        exit(0);
    }

   //对石子的位子排序————————————————————————————    
    int temp;
    for(i=0;i<S_num-1;i++)
        for(int k=i+1;k<S_num;k++)
            if(Bridge[k]<Bridge[i])
            {
                temp=Bridge[k];
                Bridge[k]=Bridge[i];
                Bridge[i]=temp;
            }
    

    dp=new int[D_max+2];
    Menkan=D_min*D_min/(D_max-D_min)+D_max+1; //?
    Min=D_max+1;

    
    for(i=0;i<D_max+2;i++)
        dp[i]=0;
    
    //D_min,D_max不等的情况求最优解————————————————————
    int j,k;
    for(j=S_num,i=L_bridge;i>=0;)
    {
        //if(i=-1) break;
        
        int D;
        if(j<1) D=i;
        else D=i-Bridge[j-1];

        if(D>=Menkan)
        {
            for(k=0;k<=D_max;k++)
                dp[k]=dp[Min];
            i=Bridge[j-1];
            continue;
        }
        if(D==0&&i!=0)
        {
            dp[0]=1+F_min(dp,D_min,D_max);
            for(k=D_max+1;k>0;k--)
                dp[k]=dp[k-1];
            dp[Min]=F_min(dp,1,D_max);
            i--;
            j--;
            continue;
        }
        if(D<Menkan)
        {
            dp[0]=F_min(dp,D_min,D_max);
            for(k=D_max+1;k>0;k--)
                dp[k]=dp[k-1];
            dp[Min]=F_min(dp,1,D_max);
            i--;
            continue;
        }
        

    }
    cout<<"最少踩到的石子数为:"<<endl;
    cout<<dp[0];

    return 0;


}


对于这个问题的压缩,我是压缩到 D_max大小,就是跳跃的最大距离

上计算机网络的时候,看到一个滑动窗口,就类比着

先定义一个D_max大小的数组,作为一个窗口,从桥尾向前滑动,并检测下一个石子的位置,若大于

“门槛”,就将窗口一直移到石子前一格处

这样对空间的要求不大

8 楼


7楼能不能加点注释,我是新手,看算法没有注释很累的

9 楼

输出的是最少踩到的石子数,不是几次跳过去
那我跳一次不就是踩到一个石子吗.头和尾都没石的
样例输入:
10
2 3 5    ///这里最小距离是2..最大距离是3,,,有5个石
2 3 5 6 7//头是0尾是10中间有石2,3,5,6,7

样例输出:

2   //那最后结果不是3吗????/

10 楼

不知ls是怎么理解的啊!!你认真看看题目,最少是2次

举个2次的例子给你看看

0->2->4->6->8->10

跳了5次,其中2和6踩到石子,

所以就是两次了

我来回复

您尚未登录,请登录后再回复。点此登录或注册