【POJ-3104】Drying

103 阅读1分钟

(似乎有些超时。。)

题意

有n件衣服,若自然风干,则每分钟减少1单位水,若烘干,每分钟减少k单位水(烘干时不再考虑自然风对其影响),每次只能选取一件衣服进行烘干,问最少需要多长时间将所有衣服烘干。

 

思路

每次处理都对含水量进行从小到大排序,最大的用风干机,其余的自然风干。每次处理完后都检测数列的最后一个是否已经小于等于0,若是,则说明她前面的衣服早都已经干了(小于等于0),即所有的衣服都干了,输出当前天数即可

第一册运行OJ : 超时了 改进:排序算法太耗时,需要改进。因为除最后一个外,都减去的是相同的数(即1)。所以前面的数仍然有序,相当于把一个数插进一个已经有序的数组,采用的方法是先用二分查找到最后一个数在原数组中的位置(若有相同的,则返回那个下标,若没有相同的,则返回富豪开始改变的位置的下标,再将元素一次往后移一位)

 

 

样例
Sample Input
3
2 3 9
5

Sample Output
3
2 3 6
5

 



 

AC代码
#include <iostream>
#include<algorithm>
#include<cstdio>
using namespace std;

int search(long long* nums, long long numsSize, int target) {
    int left=0;int right=numsSize-1;
    while(left<=right)
    {
        int mid=left+(right-left)/2;
        if(target==nums[mid]) return mid;
        else if(target<nums[mid])
        {
            right=mid-1;
        }
        else
        {
            left=mid+1;
        }
    }
    return left;
}

int main()
{
    long long n;
    while(~scanf("%lld",&n))
    {
        long long i,j,maxday,k,a[100002];
    for(i=0;i<n;i++)
    {
        scanf("%lld",&a[i]);
    }
    scanf("%lld",&k);
    sort(a,a+n);
    maxday=a[n-1];   //可能所用的最长的天数,即含水最多的衣服的水量数
    for(i=0;i<maxday;i++)
    {
/*
        cout<<"之前:";
        for(int m=0;m<n;m++)
            cout<<a[m]<<" ";
        cout<<endl;
*/

        //排序后含水最多的衣服排在最后,让它用烘干机,其他的自然风干
        a[n-1]-=k;
        for(j=0;j<n-1;j++)
        {
            a[j]-=1;
        }

       //sort(a,a+n);//每次都排一下序
       
       //改进排序:先二分查找位置,再将元素依次后移
       long long loca=search(a,n,a[n-1]);
       long long temp=a[n-1];
       for(int s=n-1;s>loca;s--)
           a[s]=a[s-1];
       a[loca]=temp;


/*
        cout<<"之后:";
        for(int m=0;m<n;m++)
            cout<<a[m]<<" ";
        cout<<endl;
*/
        if(a[n-1]<=0)
        {
            printf("%d\n",i+1);
            //cout<<i+1<<endl;
            break;
        }
    }
    }
    return 0;
}

 

题源:poj.org/problem?id=…