【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 107071
  • 排名 - 231

最新评论

阅读排行榜

评论排行榜

秀·谢夫(小奶牛)在花花公子杂志上中了大奖,于是她从农村搬到了城郊的一座别墅中。可是她还常常怀念乡村的生活,总想回到原来的农村逛逛。为了环保,秀决定骑上为她量身定做的奶牛自行车(特殊的自行车,专门为牛蹄设计)。

秀大约有一吨重。同样的,秀在普通的奶牛自行车上,要想骑得平平稳稳,也不是一件容易的事。因此,调节奶牛自行车的变速器让秀心力交瘁。

帮助秀选择她的奶牛自行车前面 F (1 <= F <= 5)个齿轮和后面 R (1 <= R <= 10)个齿轮,使她的 F*R 奶牛自行车符合下面的标准:

前面齿轮的型号(齿的数量)必须在给定的范围内。
后面齿轮的型号(齿的数量)必须在给定的范围内。
在每一种齿轮组合中,传动比率就是前面齿轮的齿数除以后面齿轮的齿数所得的商。
最大的传动比率至少是最小的三倍。
齿轮组合(已排好序)相邻两项的差的的方差(见下面的例子) 应该达到最小。
按照下面的公式计算平均数与方差(xi 代表数据) :
                   1    n
          平均数 = ---  SUM xi
                   n   i=1  

                 1    n   
          方差 = ---  SUM (xi - 平均数)^2
                 n   i=1  

计算并确定最佳齿轮组合(其中 F 个前齿轮,R 个后齿轮),使方差最小(传动比率至少是 3x)。

格式
PROGRAM NAME: cowcycle
INPUT FORMAT:(file cowcycle.in)

第一行是 F 和 R,表示前齿轮和后齿轮的数量。

第二行包括 4 个数字:F1,F2(25 <= F1 < F2 <= 80),R1,R2(5 <= R1 < R2 <= 40)。从 F1 到 F2 型号的前齿轮都是可用的;从 R1 到 R2 型号的后齿轮都是可用的。至少会有一组合法的解。

OUTPUT FORMAT:(file cowcycle.out)

在第一行从小到大输出前齿轮的型号,用空格分开。在第二行从小到大输出后齿轮的型号,同样用空格分开。当然,齿轮的齿数一定是整数。

如果有多个解,输出前齿轮齿数最小的那一个(第一个齿轮齿数最小的,若第一个齿轮齿数相等,输出第二个齿轮齿数最小的……依此类推)。如果所有的前齿轮齿数都相等,照着上面的办法处理后齿轮(其实就是把第一个,第二个……齿轮分别设为第一,第二……个关键字来排序)。

SAMPLE INPUT
2 5
39 62 12 28

SAMPLE OUTPUT
39 53
12 13 15 23 27

Comment
注释:
这个问题最大的挑战就是“读懂题目”。慢慢读,不要想一步登天。如果你读不懂题目,还是得一遍一遍的把它读进去。

问题要我们找出“最佳齿轮组合”,即传动比率最接近平均数的组合。考虑下面的测试数据:

2 5
39 62 12 28

这意味着有 2 个前齿轮,型号范围在 39..62 ;5个后齿轮,型号范围在 12..28。程序必须检查所有前齿轮组成的有序对(共 62-39+1=24 种齿轮),和所有后齿轮组成的五元组(共 28-12+1=17 种齿轮)。根据组合数学原理,总共有 24!/22!/2! x 17!/5!/12! = 656,880 种可能(我是这么认为的)。

对于每一种可能,做下面的计算。举个例子来说,对于枚举到的第一种情况:前齿轮是 39 和 40,后齿轮是 12,13,14,15 和 16。

首先,计算所有可能的传动比率:

39/12 = 3.25000000000000000000
39/13 = 3.00000000000000000000
39/14 = 2.78571428571428571428
39/15 = 2.60000000000000000000
39/16 = 2.43750000000000000000
40/12 = 3.33333333333333333333
40/13 = 3.07692307692307692307
40/14 = 2.85714285714285714285
40/15 = 2.66666666666666666666
40/16 = 2.50000000000000000000

然后,对它们进行排序:

39/16 = 2.43750000000000000000
40/16 = 2.50000000000000000000
39/15 = 2.60000000000000000000
40/15 = 2.66666666666666666666
39/14 = 2.78571428571428571428
40/14 = 2.85714285714285714285
39/13 = 3.00000000000000000000
40/13 = 3.07692307692307692307
39/12 = 3.25000000000000000000
40/12 = 3.33333333333333333333

然后,计算差的绝对值:

2.43750000000000000000 - 2.50000000000000000000 = 0.06250000000000000000
2.50000000000000000000 - 2.60000000000000000000 = 0.10000000000000000000
2.60000000000000000000 - 2.66666666666666666666 = 0.06666666666666666666
2.66666666666666666666 - 2.78571428571428571428 = 0.11904761904761904762
2.78571428571428571428 - 2.85714285714285714285 = 0.07142857142857142857
2.85714285714285714285 - 3.00000000000000000000 = 0.14285714285714285715
3.00000000000000000000 - 3.07692307692307692307 = 0.07692307692307692307
3.07692307692307692307 - 3.25000000000000000000 = 0.17307692307692307693
3.25000000000000000000 - 3.33333333333333333333 = 0.08333333333333333333

然后计算平均数和方差。

平均数是(我是这么认为的)0.0995370370370370370366666.。方差大约是 0.00129798488416722。 找出使方差最小的齿轮组合。


【参考程序】:

/*
ID: XIONGNA1
PROB: cowcycle
LANG: C++
*/
#include
<iostream>
#include
<cstring>
using namespace std;
int s1[12],s2[12],ans1[12],ans2[12];
double rate[130],diff[130],minvf=0x7FFFFFFF;
int R,F,F1,F2,R1,R2,cnt;
void jisuan()
{
    
int k=0,l;
    
double sum=0,avg,vf=0,sumf=0,p;
    
for (int i=1;i<=F;i++)
        
for (int j=1;j<=R;j++)
         {
             p
=(double) s1[i]/s2[j];
             l
=++k;
            
while (rate[l-1]>=p)
             {
                 rate[l]
=rate[l-1];
                 l
--;
             }
             rate[l]
=p;
         }
    
for (int i=1;i<=cnt-1;i++)
     {
         diff[i]
=rate[i+1]-rate[i];
         sum
+=diff[i];
         sumf
+=diff[i]*diff[i];
     }
     avg
=sum/(cnt-1);
     vf
=sumf-sum*avg;
    
if (vf<minvf)
     {
         minvf
=vf;
         memcpy(ans1
+1,s1+1,sizeof(int)*F);
         memcpy(ans2
+1,s2+1,sizeof(int)*R);
     }
}
void dfs2(int k,int w)
{
    
if (k>R)
     {
        
if (s1[F]*s2[R]<3*s1[1]*s2[1]) return ;
         jisuan();
        
return ;
     }
    
for (int i=w;i<=(R2-(R-k));i++)
     {
         s2[k]
=i;
         dfs2(k
+1,i+1);
     }
}
void dfs1(int k,int w)
{
    
if (k>F)
     {
         dfs2(
1,R1);
        
return ;
     }
    
for (int i=w;i<=(F2-(F-k));i++)
     {
         s1[k]
=i;
         dfs1(k
+1,i+1);
     }
}
int main()
{
     freopen(
"cowcycle.in","r",stdin);
     freopen(
"cowcycle.out","w",stdout);
     scanf(
"%d%d",&F,&R);
     scanf(
"%d%d%d%d",&F1,&F2,&R1,&R2);
     cnt
=F*R;
     dfs1(
1,F1);
    
for (int i=1;i<=F-1;i++) printf("%d ",ans1[i]);
     printf(
"%d\n",ans1[F]);
    
for (int i=1;i<=R-1;i++) printf("%d ",ans2[i]);
     printf(
"%d\n",ans2[R]);
    
return 0;
}
posted on 2009-07-28 15:30 开拓者 阅读(335) 评论(0)  编辑 收藏 引用 所属分类: USACO 题解

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理