2017.08.12小结

来源:互联网 发布:java如何让窗口置顶 编辑:程序博客网 时间:2024/05/14 13:47

第三题:

题意是一根长度为L的木棒,加热n度之后长度变为L'=(1+n*C)*L,其中C是木棒的热膨胀系数。给出L,n,C。求木棒在加热前后中心点的距离是多少。

四个方程:(假设要求的距离为x)

L'=(1+n*C)*L

θr= 1/2*L'

sinθ= 1/2*L/r

r*r= (1/2*L)*(1/2*L) + (r-x)*(r-x)

第六题:

题意:有n件衣服,每件衣服的含水量为ai单位,每分钟他们能自然脱水1单位,有一个脱水机,每次只能对一件衣服脱水,脱水量为k单位(脱水时不自然风干),问所有衣服全部风干的最小时间是多少?

题解:首先能够想到的是可以二分查找全部自然风干的最少时间mid。但这一题不同的是在判断函数中用蛮力法判断mid是否满足条件是会出错。需要特殊处理。

#include<cstdio>

#include<cmath>

#include<cstring>

longlong  n,k;

longlong a[100010];

booldix(long long x)

{

   long long i,time=0;

   if(k==1)

    return true;

   for(i=0;i<n;++i)

   {

      if(a[i]>x)

        time+=(a[i]-x+k-2)/(k-1);

   }

   if(time>x)

    return true;

   return false;

}

 

intmain()

{

   long long max;

   long long i;

   while(scanf("%lld",&n)!=EOF)

   {

      max=0;

      for(i=0;i<n;++i)

      {

        scanf("%lld",&a[i]);

        if(max<a[i])

           max=a[i];

      }

      scanf("%lld",&k);

      long long left=0,right=max,mid;

      while(left<right-1)

      {

        mid=(left+right)/2;

        if(dix(mid))

            left=mid;

        else

            right=mid;

      }

      printf("%lld\n",right);

   }

   return 0;

}

第十四题:

题意:给出一些宽度为1,高度大于等于0的矩形,求出最大的矩形面积。

如果确定了长方形的左端点L和右端点R,那么最大可能的高度就是min{hi|L<= i < R}。

L[i] = (j<= i并且h[j-1] < h[i]的最大的j)

R[i] = (j> i并且h[j] > h[i]的最小的j)

#include<stdio.h>

#definemaxn 100000

intn;

inth[maxn];

intL[maxn], R[maxn];

intstack[maxn];

longlong max(long long a, long long b)

{

   return (a > b) ? a : b;

}

voidsolve()

{

   long long ans = 0;

   int t = 0;

   int i;

   for (i = 0; i < n; ++i)

   {

      while (t > 0 && h[stack[t-1]]>= h[i]) t--;

      L[i] = (t == 0) ? 0 : (stack[t-1] + 1);

      stack[t++] = i;

   }

   t = 0;

   for (i = n - 1; i >= 0; --i)

   {

      while (t > 0 && h[stack[t-1]]>= h[i]) t--;

      R[i] = (t == 0) ? n : stack[t-1];

      stack[t++] = i;

   }

   for (i = 0; i < n; ++i)

   {

      ans = max(ans, (long long)h[i] * (R[i] -L[i]));

   }

   printf("%lld\n", ans);

}

intmain()

{

   int i;

   while (scanf("%d", &n) != EOF&& n != 0)

   {

      for (i = 0; i < n; ++i)

        scanf("%d", &h[i]);

      solve();

   }

 

   return 0;

}

第十题:

题意是给你一段区间,求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值。

#include<iostream>

#include<cstring>

#include<cstdio>

#definell long long

usingnamespace std;

ll n;

lla[100005];

llsum[100005];

lll[100005],r[100005];

llans;

intgg;

intmain()

{

     gg=0;

     while(scanf("%lld",&n)!=EOF)

     {

         if(gg)

         cout<<endl;

         gg++;

     sum[0]=0;

     ans=-1;

     int flag=0;

     for(int i=1;i<=n;i++)

     {

         scanf("%lld",&a[i]);

         sum[i]=sum[i-1]+a[i];

     }

     a[0]=-1;a[n+1]=-1;

     l[1]=1;

     for(int i=2;i<=n;i++)

     {

         int temp=i-1;

         while(a[temp]>=a[i])

         temp=l[temp]-1;

         l[i]=temp+1;

     }

     r[n]=n;

     for (int i=n-1;i>=1;i--)

     {

         int temp=i+1;

         while(a[temp]>=a[i])

         temp=r[temp]+1;

         r[i]=temp-1;

     }

     for(int i=1;i<=n;i++)

     {

         ll ggg=(sum[r[i]]-sum[l[i]-1])*a[i];

         if(ggg>ans)

         flag=i;

         ans=max(ans,ggg);

     }

     printf("%lld\n",ans);

     printf("%lld%lld\n",l[flag],r[flag]);

     }

     return 0;

}

 

原创粉丝点击