暑假习题 六

来源:互联网 发布:如何用ps制作淘宝店招 编辑:程序博客网 时间:2024/05/16 19:02

时间计算
【问题描述】
有一天,我做了个梦,梦见我很荣幸的接到了猪八戒的邀请,到天宫陪他吃酒。我犹豫了。天上一日,人间一年啊!当然,我是个闲人,一年之中也没有多少时日是必须在人间的,因此,我希望选一个最长的空闲时间段,使我在天上待的时间尽量长。记住,今年是4000年。天上一天也是24小时,每小时60分,每分60秒。

【输入数据】
输入文件的第一行是一个非负整数 N,表示4000年中必须呆在人间的天数,以下共N行,每行两个用空格隔开的正整数,即日期(月,日),输入文件保证无错误,日期无重复。

【输出数据】
输出文件仅有一行包含一个非负整数,即在天上的时间(四舍五入精确到秒)。

【样例输入】heaven.in
2
3 8
12 2

【样例输出】heaven.out
63266

分析:
模拟。。。。。
4000年是闰年,用一个数组存下各个月的日子。
那后看每段时间的长度,找到最长的一段,进行计算注意四舍五入。

#include <cstdio>#include <cstring>#define maxn 380const double time=86400;const int totday=366; bool rq[maxn];int n;const int day[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};int days[13];void init(){ scanf("%d",&n); memset(rq,false,sizeof(rq)); int i,m,d; for(i=1;i<=12;i++)  days[i]=days[i-1]+day[i-1]; for(i=1;i<=n;i++)  {   scanf("%d%d",&m,&d);    rq[days[m]+d]=true;     }}void calc(){ int tmp=0,i,ans=0; for(i=1;i<=totday;i++)  if(rq[i])   {   if(ans<tmp)      ans=tmp;     tmp=0;   }  else    tmp++; if(ans<tmp)    ans=tmp;   double t=double(ans)/double(totday)*time; printf("%.0lf",t);}int main(){ init(); calc(); return 0;    }

最优时间表
【问题描述】
一台精密仪器的工作时间为 n 个时间单位。与仪器工作时间同步进行若干仪器维修程序。一旦启动维修程序,仪器必须进入维修程序。如果只有一个维修程序启动,则必须进入该维修程序。如果在同一时刻有多个维修程序,可任选进入其中的一个维修程序。维修程序必须从头开始,不能从中间插入。一个维修程序从第s个时间单位开始,持续t个时间单位,则该维修程序在第s+t-1个时间单位结束。为了提高仪器使用率,希望安排尽可能少的维修时间。
编程任务:对于给定的维修程序时间表,编程计算最优时间表。

【输入数据】
第 1 行有2 个正整数n和 k(1≤n,k≤9999)。n表示仪器的工作时间单位;k是维修程序数。接下来的k行中,每行有2 个表示维修程序的整数s和 t,该维修程序从第s个时间单位开始,持续t个时间单位。

【输出数据】
最少维修时间。

【样例输入】sche.in
15 6
1 2
1 6
4 11
8 5
8 1
11 5

【样例输出】sche.out
11
分析:
动态规划
设mt(i)表示从第i个时间单位开始到第n个时间单位结束的最短维修时间,则mt(i)具有最优子结构性质,且满足如下递归式:
当时间单位i有多个维修程序时,mt(i)=min{mt(i+tj)};
sj=i
当时间单位i没有维修程序时,mt(i)=mt(i+1)-1 。
初始值为mt(n+1)=n 。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;struct node{     int s,t;     bool operator < (const node &a)const      {          return s<a.s;     }}e[50000];int m;int n,k;int ans[10005];int main(){  scanf("%d%d",&n,&k);  for(int i=0;i<k; i++)  {scanf("%d%d",&e[i].s,&e[i].t);  }  sort(e,e+k);  for(int i=n+1 ;i>=1 ;i--)  {   if(i>e[k-1].s)ans[i]=0;   else ans[i]=-1;  }  for(int j=k-1;j>=0;j--)  {    if(ans[e[j].s] == -1)    {      if(j!=(k-1))      for(int i=e[j].s+1 ;i<e[j+1].s ;i++)       ans[i] = ans[e[j+1].s];       ans[e[j].s] = ans[e[j].s+e[j].t]+e[j].t;    }      else {        if(ans[e[j].s] > ans[e[j].s+e[j].t]+e[j].t)        ans[e[j].s] = ans[e[j].s+e[j].s]+e[j].t;        }  }     for (m=0 ; m<e[0].s ;m++)     ans[m] = ans[e[0].s];   printf("%d",ans[m]);   return 0;}

登山机器人
【问题描述】
登山机器人是一个极富挑战性的高技术密集型科学研究项目,它为研究发展多智能体系统和多机器人之间的合作与对抗提供了生动的研究模型。
登山机器人可以携带有限的能量。在登山过程中,登山机器人需要消耗一定能量,连续攀登的路程越长,其攀登的速度就越慢。在对 n 种不同类型的机器人作性能测试时,测定出每个机器人连续攀登1米,2米,…,k米所用的时间。现在要对这n个机器人进行综合性能测试,举行机器人接力攀登演习。攀登的总高度为 m米。规定每个机器人只能攀登 1次,每次至少攀登1米,最多攀登k 米,而且每个机器人攀登的高度必须是整数,即只能在整米处接力。安排每个机器人攀登适当的高度,使完成接力攀登用的时间最短。
编程任务:给定 n 个登山机器人接力攀登的总高度m,以及每个机器人连续攀登 1 米,2 米,…,k米所用的时间,编程计算最优攀登方案。

【输入数据】
第一行是正整数n(1≤n≤1000),k(1≤k≤400)和 m(1≤m≤10000)分别表示机器人的个数,每个机器人最多可以攀登的高度,和攀登的总高度。接下来的 n行中,每行有 k个正整数,分别表示机器人连续攀登1米,2米,…,k 米所用的时间。

【输出数据】
最短攀登时间。

【样例输入】robot.in
5 10 25
24 49 75 102 130 160 192 230 270 320
23 48 75 103 139 181 224 274 344 415
22 49 80 180 280 380 480 580 680 780
25 51 80 120 170 220 270 320 370 420
23 49 79 118 158 200 250 300 350 400

【样例输出】robot.out
727

登山机器人(贪心)
贪心策略:每次选择所用时间最少的机器人。

#include <cstdio>#define maxn 1010#define maxm 10010#define maxk 410#define big 0x7fffffffint rec[maxn][maxm],dat[maxn][maxk];bool used[maxn][maxm];int n,k,m;int s(int a,int h){ if(h==m)  return 0; if(a==n)  {   if(m-h<=k)    return dat[a][m-h];    return big;   } if(used[a][h])  return rec[a][h]; int t=big,t1,i; for(i=1;i<=k;i++)  {   if(h+i>m)    break;   t1=s(a+1,h+i);   if(t1 < big)    t1+=dat[a][i];   if(t>t1)    t=t1;                    }       used[a][h]=t; rec[a][h]=t; return t;     } void init(){ scanf("%d%d%d",&n,&k,&m); int i,j; for(i=1;i<=n;i++)   for(j=1;j<=k;j++)   scanf("%d",&dat[i][j]);     }int main(){ init(); printf("%d",s(1,0)); return 0;}

三角形牧场
【问题描述】
和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师Hei想建造围有漂亮白色栅栏的三角形牧场。她拥有N(3≤N≤40)块木板,每块的长度Li(1≤Li≤40)都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。
请帮助Hei小姐构造这样的牧场,并计算出这个最大牧场的面积。

【输入】
第1行:一个整数N
第2..N+1行:每行包含一个整数,即是木板长度。

【输出】
仅一个整数:最大牧场面积乘以100然后舍尾的结果。如果无法构建,输出-1。

【样例】
pasture.in pasture.out
5 692
1
1
3
3
4

【样例解释】
692=舍尾后的(100×三角形面积),此三角形为等边三角形,边长为4。

分析:
二维的背包问题。
将所有的木板当作背包,木板的长度作为背包的重量。与普通背包问题不同的是,这里有两个背包。所以,我们要求的不是重量w是否能得到,而是一个重量二元组(w0, w1)是否能得到。求解的方法与普通背包问题基本相同,只不过状态是二维的。
求得所有可以得到的二元组后,枚举所有的二元组。对于任意的(w0, w1),w0, w1,w—w0—w1(w表示所有背包的总重量)即是对应的三角形三边之长(可能是非法三角形)。这些三角形中面积最大者就是我们所求的答案。
方法二 :动态规划,f[i][j][k]表示前i块木板能不能拼成三角形两边为j和k的状态。
然后枚举两边,用总长减去两边长算出第三边,用海伦公式算出面积,更新数值

#include<cstdio>#include<cmath>bool f[41][1500][1500];int tot,a[41],n;double ans;double S(double a,double b,double c){       double p=(a+b+c)/2;       return sqrt(p*(p-a)*(p-b)*(p-c));}       int main(){    scanf("%d",&n);    for (int i=1;i<=n;++i)    {        scanf("%d",&a[i]);        tot+=a[i];    }    f[0][0][0]=1;    for (int i=1;i<=n;++i)        for (int j=0;j<=tot/2+1;++j)            for (int k=0;k<=tot/2+1;++k)                f[i][j][k]=((f[i-1][j][k])||((a[i]<=j)&&(f[i-1][j-a[i]][k]))||((a[i]<=k)&&(f[i-1][j][k-a[i]])));    for (int i=1;i<=tot/2+1;++i)        for (int j=1;j<=tot/2+1;++j)            if (f[n][i][j])            {                 int k=tot-i-j;                 if ((k+i>j)&&(i+j>k)&&(j+k>i))                {                  double tem=S(i,j,k);                  if (tem>ans) ans=tem;                }                      }    if (ans!=0) printf("%d\n",(int)(ans*100));    else printf("-1\n");    return 0;}
0 0
原创粉丝点击