您的位置:首页 > 其它

7.11.实验 解题参考

2016-07-11 13:01 232 查看
ProblemA(HDU1008)

直接模拟,每个请求根据状态累计时间。

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n;
int a[1000];
while(scanf("%d",&n)!=EOF && n)
{
int i;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
int sum;
sum=a[0]*6+5;
for(i=0;i<n-1;i++)
{
if(a[i+1]>a[i]) sum+=(a[i+1]-a[i])*6+5;
if(a[i+1]<a[i]) sum+=(a[i]-a[i+1])*4+5;
if(a[i+1]==a[i]) sum+=5;
}
printf("%d\n",sum);
}
return 0;
}


ProblemB(HDU1009)

一共有n个房子,每个房子里有老鼠喜欢吃的javabeans,但是每个房间里的javabeans的价格不一样。老鼠用m元,问m元最多可以卖多少javabeans,其中每个房间里的javabeans可以被分割。

很明显就是个部分背包,算法是贪心。先求单价,然后排个序就行了。

#include<stdio.h>
#include<algorithm>
using namespace std;
struct Trade
{
int j,f;
double percent;
}mouse[3001];
bool cmp(Trade a,Trade b)
{
return a.percent>b.percent;
}
int main()
{
int n,m;
while(scanf("%d%d",&m,&n)!=EOF&&(n!=-1||m!=-1))
{
int i;

for(i=0;i<n;i++)
{
scanf("%d%d",&mouse[i].j,&mouse[i].f);
mouse[i].percent=(double)mouse[i].j/mouse[i].f;
}
sort(mouse,mouse+n,cmp);
double sum=0;
for(i=0;i<n;i++)
{
if(m>mouse[i].f)
{
sum+=mouse[i].j;
m-=mouse[i].f;
}
else
{
sum+=mouse[i].percent*m;
m=0;
break;
}

}

printf("%.3lf\n",sum);

}
return 0;
}


ProblemC(HDU1076)

简单模拟,从这一年开始向后找,每一年一次判断是否为闰年,直到找到第n个润年。

#include <stdio.h>
using namespace std;
bool leap(int y){
return y%4==0&&y%100||y%400==0;
}
int main(){
int y,T,n,cnt,i;
scanf("%d",&T);
while(T--){
scanf("%d%d",&y,&n);
cnt=0;
for(i=y;cnt<n;i++)
if(leap(i))
cnt++;
printf("%d\n",i-1);
}
return 0;
}


ProblemD(HDU1201)

这也是个纯模拟就可以做的,比上一题略复杂一点。主要思路要注意的有:

<1>将出生年所经历的天数与18岁生日那年度过的天数合在一起算作一年。

<2>不考虑闰年,则18年共度过18*365天。

<3>考虑闰年,首先出生年与18岁生日合在一起那年要单独考虑,其他年份只要是闰年,则总天数加1天即可。

<4>单独考虑合在一起年份,若出生年是闰年,并且在2月29日之前出生的,那么他(她)必定经过2月29日这天,总天数加1,对于18岁那年,若该年是闰年,并且在2月28日之后出生的,他(她)同样必定经过2月29这天,所以总天数加1.

<5>如果是在2月29日出生,18年时必定过不了生日了,输出-1即可。

#include <stdio.h>
using namespace std;
int leap(int y)
{
if(y%400 == 0 || (y%4 == 0 && y%100!=0))
return 1;
return 0;
}
int main()
{
int y,m,d,i,n;
scanf("%d",&n);
while(n--)
{
int sum = 0;
scanf("%d-%d-%d",&y,&m,&d);
if(m == 2 && d ==
4000
29)
{
printf("-1\n");
continue;
}
sum = 365*18;
if(leap(y) && m<3)
sum++;
if(leap(y+18) && m>=3)
sum++;
for(i = y+1; i<y+18; i++)
if(leap(i))
sum++;
printf("%d\n",sum);
}
return 0;
}


ProblemE(HDU1049)

这一题可以直接模拟做,用循环,注意奇偶的情况。

#include<iostream>
using namespace std;
int main()
{
int n,u,d,i,j,time;
while(cin>>n>>u>>d)
{   if(n==0) break;
time=1;
while(n>0) //这里一开始写的是while(n) 没注意到n<0也是真的 ,bug一次
{  if(time%2!=0)
n-=u;
else
n+=d;
time++;
}
cout<<(time-1)<<endl;
}
return 0;
}


也可以直接总结,理出公式,算是贪心了吧。。

总长为n,上升一秒走u,休息一秒下降d。相当于每两秒走(u-d);

先n-u,得到过了多少个u-d后超过n-u;

int t=(n-u)/(u-d);

if(t*(u-d)<(n-u)) t++;

t*=2;t++;

就是最后一秒可以一步到达~~~

#include<stdio.h>
int main()
{
int n,u,d;
while(scanf("%d%d%d",&n,&u,&d),n)
{
int t=(n-u)/(u-d);
if(t*(u-d)<(n-u)) t++;
t*=2;
t++;
printf("%d\n",t);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: