zoukankan      html  css  js  c++  java
  • 2014年百度之星程序设计大赛

    Problem Description
    有非常多从磁盘读取数据的需求,包含顺序读取、随机读取。为了提高效率,须要人为安排磁盘读取。然而,在现实中,这样的做法非常复杂。我们考虑一个相对简单的场景。磁盘有很多轨道,每一个轨道有很多扇区,用于存储数据。当我们想在特定扇区来读取数据时,磁头须要跳转到特定的轨道、详细扇区进行读取操作。为了简单,我们如果磁头能够在某个轨道顺时针或逆时针匀速旋转,旋转一周的时间是360个单位时间。磁头也能够任意移动到某个轨道进行读取,每跳转到一个相邻轨道的时间为400个单位时间,跳转前后磁头所在扇区位置不变。一次读取数据的时间为10个单位时间,读取前后磁头所在的扇区位置不变。磁头同一时候仅仅能做一件事:跳转轨道,旋转或读取。如今,须要在磁盘读取一组数据,如果每一个轨道至多有一个读取请求,这个读取的扇区是轨道上分布在 0到359内的一个整数点扇区,即轨道的某个360等分点。磁头的起始点在0轨道0扇区,此时没有数据读取。在完毕全部读取后,磁头须要回到0轨道0扇区的始点位置。请问完毕给定的读取所需的最小时间。

    Input
    输入的第一行包括一个整数M(0<M<=100),表示測试数据的组数。对于每组測试数据,第一行包括一个整数N(0<N<=1000),表示要读取的数据的数量。之后每行包括两个整数T和S(0<T<=1000,0<= S<360),表示每一个数据的磁道和扇区,磁道是按升序排列,而且没有反复。
     
    Output
    对于每组測试数据,输出一个整数,表示完毕所有读取所需的时间。
     
    Sample Input
    3
    1
    1 10
    3
    1 20
    3 30
    5 10
    2
    1 10
    2 11
     
    Sample Output
    830
    4090
    1642


    解题思路:

    这题目和双调欧几里得旅行商问题思想是一样的,从一个点出发,不反复的到达每个点,最后到达起点,求最短距离。

    现学的这个,參考:

    http://www.cppblog.com/doer-xee/archive/2009/11/30/102296.html

    http://www.cnblogs.com/-sunshine/archive/2012/07/23/2605251.html

    http://blog.csdn.net/xiajun07061225/article/details/8092247

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=1010;
    const int inf=0x7fffffff;
    int cas;
    int n;
    struct Node
    {
        int t,s;
    }node[maxn];
    double dp[maxn][maxn];
    
    int dis(Node a,Node b)//计算两个磁道读取数据位置的距离(包含磁道距离+扇区距离)
    {
        int ci=abs(a.t-b.t)*400;
        int MAX=(a.s>b.s?a.s:b.s);
        int MIN=(a.s<b.s?a.s:b.s);
        int shan=min(MAX-MIN,360-MAX+MIN);
        return ci+shan;
    }
    int DP(int n)//双调欧几里得旅行商问题算法
    {
        dp[1][2]=dis(node[1],node[2]);
        for(int j=3;j<=n;j++)
        {
            for(int i=1;i<=j-2;i++)
                dp[i][j]=dp[i][j-1]+dis(node[j-1],node[j]);
            dp[j-1][j]=inf;
            for(int k=1;k<=j-2;k++)
            {
                int temp=dp[k][j-1]+dis(node[k],node[j]);
                if(temp<dp[j-1][j])
                    dp[j-1][j]=temp;
            }
        }
        dp[n][n]=dp[n-1][n]+dis(node[n-1],node[n]);
        return dp[n][n];
    
    }
    int main()
    {
        cin>>cas;
        while(cas--)
        {
            cin>>n;
            node[1].t=0,node[1].s=0;
            for(int i=1;i<=n;i++)
                cin>>node[i+1].t>>node[i+1].s;
            n++;
            cout<<DP(n)+10*(n-1)<<endl;//别忘了加上读取数据的时间
        }
        return 0;
    }


  • 相关阅读:
    二进制位运算
    Leetcode 373. Find K Pairs with Smallest Sums
    priority_queue的用法
    Leetcode 110. Balanced Binary Tree
    Leetcode 104. Maximum Depth of Binary Tree
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 64. Minimum Path Sum
    Leetcode 63. Unique Paths II
    经典的递归练习
    案例:java中的基本排序
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4375891.html
Copyright © 2011-2022 走看看