C++之练习题2

2.已知:有6*6 的大箱子和1*1,2*2,3*3,4*4, 5*5,6*6 的木块,箱子高度和木块一样
问:给定各种木块的数目,求最少需要多少个大箱 子来装?
例如:
输入:0 0 4 0 0 1 -〉输出2

输入:7 5 1 0 0 0 -〉输出1

解题思想:先放大的,后放小的
1.6*6的木块每个占用一个新箱子;
2.5*5的木块每个占用一个新箱子,余下11个1*1的空格;
3.4*4的木块每个占用一个新箱子,余下5个2*2的空格;
4.3*3的木块每4个占用新一个箱子,不足4个也占一个新箱子,分情况余下不同数目的空格;
5.2*2的木块先填空格,空格不足开新箱子,每9个2*2 的木块占一个新箱子;
6.1*1的木块先填空格,空格不足开新箱子,每36个占一个新箱子。

构造法:
6*6,5*5,4*4 ,3*3,2*2,1*1 个数b6 b5 b4 b3 b2 b1
nTotal - 箱子数:
(1)先放好所有6 * 6, 5 * 5, 4 * 4 和3 * 3 的木块
          nTotal = b6 + b5 + b4 + (b3+3)/4
          4*4, 5*5, 6*6 单独开箱子
          3*3 每4个占一个箱子,余下的占一个箱子

(2) 再把2 * 2的塞到放有3*3木块的箱子里
        设一个数组:
            int Contain2[4] = { 0, 5, 3, 1 };
            Contain2[i] 表示当3*3木块的数目除以4的余数分别是0,1,2,3时,会产生多少个能放2*2木块的空格。
            用数组纪录某些事实,比写if else 方便
            放完2*2的木块后,再算一下有多少1*1的空格,能否把1*1的木块都填进去,如果不能,也容易算出还要加多少个箱子

(3) 计算放好6*6,5*5,4*4,3*3后留下多少空格能放2*2
           c2 = 5 * b4 + Contain2[b3 % 4];
(4) 在放好2*2的木块后,算留下多少空格能放1*1
           c1 = 36 * nTotal - 36 * b6 - 25 * b5 - 16 * b4 - 9 * b3 - 4 * b2;

#include <iostream>
using namespace std;
int main() {
int b6,b5,b4,b3,b2,b1; //不同大小的木块个数
int nTotal = 0; //最少需要的箱子数目
int c1; //当前能放1*1 木块的空格数目
int c2; //当前能放2*2 木块的空格数目
int Contain2[4] = { 0, 5, 3, 1 };
while(1){
cin>>b1>>b2>>b3>>b4>>b5>>b6;
if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0
&& b5 == 0 && b6 == 0) break;
nTotal = b6 + b5 + b4 + (b3 + 3)/4;
//这里有一个小技巧-(b3+3)/4 正好等于b3除以4向上取整的结果,下同
c2 = 5 * b4 + Contain2[b3 % 4];
if(b2 > c2) nTotal += (b2 - c2 + 8 ) / 9;
c1 = 36 * nTotal - 36 * b6 - 25 * b5 - 16 * b4 - 9 * b3 - 4 * b2;
if(b1 > c1) nTotal += ( b1 - c1 + 35 ) / 36;
cout << nTotal << endl;
}
return 0;
}

3.人生来就有三个生理周期,分别为体力、感情和智力 周期,它们的周期长度为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表 现出色。例如,智力周期的高峰,人会思维敏捷,精力 容易高度集中。因为三个周期的长度不同,所以通常三 个周期的高峰不会落在同一天。对于每个人,我们想知 道何时三个高峰落在同一天。对每个周期,我们都给出 了某一个高峰出现的日子(用高峰日是当年的第几天表 示,1月1日算第0天)。

现给定一个日子(也用当年的第几天表示),要求你输 出从给定日子开始(不包括给定日子)下一次三个高峰 落在同一天的时间(用距给定日子的天数来表示)。例 如:给定日子为当年第10天,如果下次出现三个高峰同日的时间是当年第12天,则输出2(注意这里不是3)

输入
输入四个整数:p, e, i和d。p, e, i分别表示体力、情感和智力高峰出现的日子(即第p天,第e天和第d天)。d 是给定的日子(第d天),可能小于p, e, 或i。d 是非负的并且小于365, 数据保证所求的日子会在第21252天前。数据以一行4个-1结束
输出
从给定日子起,下一次三个高峰同天的日子距离给定日 子的天数。

问题分析
令所求的时间为第x天,则x具有如下性质:
1) D < x <= 21252
2) (x-p)%23=0
3) (x-e)%28=0
4) (x-i)%33=0
62 173

程序设计
// 读入p, e, i, d
// j从d+1 循环到21252,如果(j-p)%23==0,跳出循环
// j从上次跳出循环的值循环到21252,
如果(j-e)%28==0,跳出循环
// j从上次跳出循环的值循环到21252,
如果(j-i)%33==0,跳出循环
// 输出j-d

#include<iostream> //生理周期using namespace std;
int main(){
int p,e,i,d,j,no=1;
cin >> p >> e >> i >> d;
while(p!=-1 && e!=-1 && i!=-1 && d!=-1){
for(j=d+1; j<=21252; j++)
if((j-p)%23 == 0) break;
for( ; j<=21252; j=j+23)
if ((j-e)%28 == 0) break;
for( ; j<=21252; j=j+23*28)
if ((j-i)%33 == 0) break;
cout << "Case " << no;
cout << ": the next triple peak occurs in ";
cout<< j-d << " days." << endl;
cin >> p >> e >> i>> d;
no++;
}
return 0;
}








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值