POJ 3618 Exploration

简单题。。。 但要注意理解题意,每次都从都选离原点最近的未访问过的点走。。 

思路: 将-100,000 ≤ xi ≤ 100,000范围 转换成 0 ~ 200,000   OFFSET(偏移量) 100000 ,由于我是用bool visit[N]。。。虽然代码有点长。。但跑出来的效率比较高。。


//376K  63MS
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <climits>
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
#define N  200005
#define OFFSET 100000       //作为偏移量
using namespace std ;

bool visit[N] ;

void Exploration ( const double t )
{
    double count_time ;
    count_time = 0 ;
    int ans ;           //记录参观的景点数
    ans = 0 ;
    int index ;
    index = OFFSET ;
    while ( count_time <= t )
    {
        int mark1 , mark2 ;     //每次从100000向左,右搜索第一个未遍历过的点
        int i , k ;
        for (  i = OFFSET , k = OFFSET ; i < N || k >= 0 ; i ++ , k -- )
        {
            if ( visit[i] )
            {
                mark1 = i ;
                break ;
            }
            if ( visit[k] )
            {
                mark2 = k ;
                break ;
            }
        }
        double dis1 , dis2 ;
        dis1 = fabs ( (double)OFFSET - (double)mark1 ) ;
        dis2 = fabs ( (double)OFFSET - (double)mark2 ) ;
        int min ;
        if ( dis1 < dis2 )
        {
            min = mark1 ;
        }
        else
        {
            min = mark2 ;
        }
        if ( count_time + fabs( (double)min - index ) > t )
        {
            break ;
        }
        ans ++ ;
        count_time  += fabs ( (double)min - index ) ;       //记录时间
        index = min ;                       //新参观的landmark
        visit[index] = false ;
        mark1 = mark2 = INT_MAX ;               //注意重置
    }
    printf ("%d\n" , ans ) ;
}

int
main ( )
{
    double t ;
    int n ;
    while ( EOF != scanf ("%lf%d" , & t , & n  ) )
    {
        memset ( visit , 0 , sizeof ( visit ) ) ;
        for ( int i = 1 ; i <= n ; i ++ )
        {
            int index ;
            scanf ("%d" , & index ) ;
            index += OFFSET ;
            visit[index] = true ;
        }
        Exploration ( t ) ;
    }
    return 0 ;
}

 



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值