POJ - 2586解题文档
POJ - 2586
计算机机械师(简称ACM)遭遇千年虫问题,失去了编制微软公司年报所必需的一些重要资料。
所有他们记住的是MS inc .在1999年每个月都会发布盈余或赤字,每个月当MS inc .发布盈余,盈余的量为s,每个月当MS inc .公布的赤字,赤字的量是d。他们不记得哪个月或多少个月发布了盈余或赤字。与其他公司不同的是,MS Inc.在一年中连续发布5个月的收益。ACM知道有8个报告都报告了赤字,但他们不知道有多少。总会计师几乎可以肯定,MS Inc.将在1999年全年实现盈余。差不多,但不完全是。
写一个程序,决定MS Inc.在1999年是否有赤字,或者1999年是否可能有盈余,他们可以发布的最大盈余数额是多少。
题意
已知一个公司在某一年中,【每个月要么固定盈利s、要么固定亏损d】。
但是具体哪个月盈利、那个月亏损却不得而知。
不过可以肯定的是,这一年中,【任意的连续5个月盈亏和必定是亏损(< 0)】。
问这年是否存在盈利的可能,若可能盈利,【最大的盈利额】是多少
解题思路
由于一年只有12个月,完全可以举几个例子来找规律
由于要求盈利最大化,所以应该把亏损的月份往后靠
例如
59 59 59 59 237 59 59 59 59 237 59 59
375 375 375 743 743 375 375 375 743 743 375 375
200000 200000 200000 200000 849694 200000 200000 200000 200000 849694 200000 200000
2500000 2500000 2500000 8000000 8000000 2500000 2500000 2500000 8000000 8000000 2500000 2500000
可以看出来其具有循环性
然而最开始是暴力解题(错误代码)
#include<stdio.h>
#include<math.h>
int main()
{
int s,d,i,h,sum,a[12],j;
while(scanf("%d%d",&s,&d)!=EOF)
{
for(i=0;i<11;i++)
{
a[i]=s;//将12个月都设置为盈利
}
for(i=0;i<6;i++)//此循环会导致重复替代
{
h=a[i]+a[i+1]+a[i+2]+a[i+3]+a[i+4];
for(j=4;j>1;j--)
{
if(h>0)
{
a[i+j]=d;
h=h-d;
}
}
}
for(i=0;i<11;i++)
{
if(a[i]==s)
sum=sum+a[i];
else
sum=sum-a[i];
}
if(sum>0)
printf("%d\n",sum);
else
printf("Deficit\n");
}
return 0;
}
下面是在发现循环后写出的正确代码
#include<stdio.h>
#include<math.h>
int main()
{
int s,d,i,h,sum=0;
while(scanf("%d%d",&s,&d)!=EOF)
{
for(i=1;i<=5;i++)
{
if(i*d>(5-i)*s)
{
break;
}
}
i=5-i;
if(i==1)
{
i=3;
}
else if(i>1)
{
i=i+i+2;
}
sum=i*s-(12-i)*d;
if(sum>0)
printf("%d\n",sum);
else
printf("Deficit\n");
}
return 0;
}