• Poj 1054 The Troublesome Frog / OpenJudge 2812 恼人的青蛙


    1.链接地址:

    http://poj.org/problem?id=1054

    http://bailian.openjudge.cn/practice/2812

    2.题目:

    总时间限制:
    10000ms
    内存限制:
    65536kB
    描述
    在韩国,有一种小的青蛙。每到晚上,这种青蛙会跳越稻田,从而踩踏稻子。农民在早上看到被踩踏的稻子,希望找到造成最大损害的那只青蛙经过的路径。每只青蛙总是沿着一条直线跳越稻田,而且每次跳跃的距离都相同。



    如下图所示,稻田里的稻子组成一个栅格,每棵稻子位于一个格点上。而青蛙总是从稻田的一侧跳进稻田,然后沿着某条直线穿越稻田,从另一侧跳出去



    如下图所示,可能会有多只青蛙从稻田穿越。青蛙的每一跳都恰好踩在一棵水稻上,将这棵水稻拍倒。有些水稻可能被多只青蛙踩踏。当然,农民所见到的是图4中的情形,并看不到图3中的直线,也见不到别人家田里被踩踏的水稻,。


    根据图4,农民能够构造出青蛙穿越稻田时的行走路径,并且只关心那些在穿越稻田时至少踩踏了3棵水稻的青蛙。因此,每条青蛙行走路径上至少包括3棵被踩踏的水稻。而在一条青蛙行走路径的直线上,也可能会有些被踩踏的水稻不属于该行走路径
    ①不是一条行走路径:只有两棵被踩踏的水稻;
    ②是一条行走路径,但不包括(2,6)上的水道;
    ③不是一条行走路径:虽然有3棵被踩踏的水稻,但这三棵水稻之间的距离间隔不相等。

    请你写一个程序,确定:在一条青蛙行走路径中,最多有多少颗水稻被踩踏。例如,图4的答案是7,因为第6行上全部水稻恰好构成一条青蛙行走路径。
    输入
    从标准输入设备上读入数据。第一行上两个整数R、C,分别表示稻田中水稻的行数和列数,1≤R、C≤5000。第二行是一个整数N,表示被踩 踏的水稻数量, 3≤N≤5000。在剩下的N行中,每行有两个整数,分别是一颗被踩踏水稻的行号(1~R)和列号(1~C),两个整数用一个空格隔开。而且,每棵被踩踏 水稻只被列出一次。
    输出
    从标准输出设备上输出一个整数。如果在稻田中存在青蛙行走路径,则输出包含最多水稻的青蛙行走路径中的水稻数量,否则输出0。
    样例输入
    6 7
    14 
    2 1 
    6 6 
    4 2 
    2 5 
    2 6 
    2 7 
    3 4 
    6 1 
    6 2 
    2 3 
    6 3 
    6 4 
    6 5 
    6 7 
    样例输出
    7
    
    来源
    1054

    3.思路:

    枚举,数据量较大,要做优化

    首先要判断是否可能为步数最多的,不可能则跳过无需判断

    4.代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 
     5 using namespace std;
     6 
     7 struct STEP
     8 {
     9     int x;
    10     int y;
    11 };
    12 
    13 int cmp(const void *a,const void *b)
    14 {
    15     STEP step1 = *((STEP *)a);
    16     STEP step2 = *((STEP *)b);
    17     if(step1.x == step2.x) return step1.y - step2.y;
    18     else return step1.x - step2.x;
    19 }
    20 
    21 int main()
    22 {
    23     int i,j;
    24 
    25     int r,c;
    26     cin>>r>>c;
    27 
    28     int    n;
    29     cin>>n;
    30     STEP *steps = new STEP[n];
    31 
    32     for(i = 0; i < n; ++i)
    33     {
    34         cin>>steps[i].x>>steps[i].y;
    35     }
    36     qsort(steps,n,sizeof(STEP),cmp);
    37 
    38     int dx,dy,dx0,dy0,dxk,dyk;
    39     int max = 0;
    40     int count;
    41     for(i = 0;i < n-1; ++i)
    42     {
    43         for(j = i + 1; j < n; ++j)
    44         {
    45             dx = steps[j].x - steps[i].x;
    46             dy = steps[j].y - steps[i].y;
    47             
    48             dx0 = steps[i].x - dx;
    49             dy0 = steps[i].y - dy;
    50             if((dx0 >0 && dx0 <= r) && (dy0 > 0 && dy0 <= c)) continue;
    51 
    52             dxk = dx0 + (max + 1) * dx;
    53             dyk = dy0 + (max + 1) * dy;
    54             if(dxk <= 0 || dxk > r || dyk <= 0 || dyk > c) continue;
    55 
    56             dxk = steps[j].x + dx;
    57             dyk = steps[j].y + dy;
    58             count = 2;
    59             while((dxk >0 && dxk <= r) && (dyk > 0 && dyk <= c))
    60             {
    61                 STEP step;
    62                 step.x = dxk;
    63                 step.y = dyk;
    64 
    65                 if(bsearch(&step,steps,n,sizeof(STEP),cmp) == NULL) break;
    66                 
    67                 count++;
    68                 dxk += dx;
    69                 dyk += dy;
    70             }
    71             if(!((dxk >0 && dxk <= r) && (dyk > 0 && dyk <= c)))
    72             {
    73                 if(count > max && count > 2) max = count;
    74             }
    75         }
    76     }
    77     cout<<max<<endl;
    78 
    79     delete [] steps;
    80     return 0;
    81 }
  • 相关阅读:
    一个printf(结构体指针)引发的血案
    C语言指针从底层原理到花式技巧,用图文和代码帮你讲解透彻
    利用C语言中的setjmp和longjmp,来实现异常捕获和协程
    提高代码逼格的利器:宏定义从入门到放弃
    我最喜欢的进程之间通信方式消息总线
    推荐一个阅读代码、文档的利器:屏幕贴图工具
    计算机网络基础知识总结
    vi指令总结
    LVS 负载均衡器理论基础及抓包分析
    Linux命令总结大全,包含所有linux命令
  • 原文地址:https://www.cnblogs.com/mobileliker/p/3548865.html
Copyright © 2020-2023  润新知