C++寒假班错题集(1.30)

文章讨论了如何高效地解决关于数字拆分(如2的次幂问题,排除2^0的情况)和分糖果问题(如约瑟夫问题变种),以及如何在限制条件下找到最优解,如最大化奖励或找到覆盖范围的最小糖果数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

错题题目

        1.优秀的拆分

        2.小苹果

        3.分糖果

 优秀的拆分

样例: 

我们先来看一下样例是怎么玩的
先说 6 是不是一个优秀的拆分,他可以分为 2 的 2 次幂,和 2 的 1 次幂,所以它是一个优秀的拆分,输出 2 ^ 2 也就是4  , 和 2  ^ 1  也就是2。但是这里有一个坑 2 ^ 0算不算优秀的拆分,注意审题呀,他说的是 2 的正整数次幂,所以2^ 0不算优秀的拆分

那我们来看一下这个题的思路:

既然知道了2 ^ 0不算优秀的拆分,那首先奇数是不是一定不算优秀的拆分。我们可以先判断是不是奇数,如果是直接输出-1,否则就把首位去掉,将n转换成二进制,如果在二进制的某一位上为1,则将对应的2的i次方存进数组中 ,为了从大到小输出,是不是要翻转一下数组(直接逆序输出也行),再输出。

标程:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n; cin>>n;
    if(n % 2 == 1) return cout<<-1, 0;
    n /= 2;
    vector<int> ans;
    //将n转换成二进制,如果在二进制的某一位上为1,则将对应的2的i次方存进数组中 
    for(int i = 2; n; i *= 2){
        if(n % 2 == 1) ans.push_back(i);     
        n /= 2;
    }
    //反转数组,达到逆序输出的效果 
    reverse(ans.begin(), ans.end());
    for(int a : ans) cout<<a<<' ';
    return 0;
}

小苹果

这个题目类似于约瑟夫问题,只不过约瑟夫是个环。

样例:

小苞的桌上一共放了 8 个苹果。
小苞第一天拿走了编号为 1、4、7 的苹果。
小苞第二天拿走了编号为 2、6 的苹果。
小苞第三天拿走了编号为 3 的苹果。
小苞第四天拿走了编号为 5 的苹果。
小苞第五天拿走了编号为 8 的苹果。

思路:

每天拿走一个,每次间隔2个,也就是+3,到底了就回来,从头拿,数量不足就一个个拿。

标程:
 

#include <bits/stdc++.h>
using namespace std;
int take(int n) {              // n个数字,每次拿走几个?
  return n / 3 + (n % 3 > 0);  // 拿走3的倍数+1
}
int f1(int n) {  // n个数字,总共能拿几次呢?
  if (n == 1) return 1;
  return 1 + f1(n - take(n));
}
// n个数字,最后一个数字第几次拿走
int f2(int n) {
  if (n % 3 == 1) return 1;    // 最后一个数字是3的余数, 直接拿走
  return 1 + f2(n - take(n));  // 可以再拿一次
}
int main() {
  int n;
  cin >> n;
  printf("%d %d\n", f1(n), f2(n));
  return 0;
}

分糖果 

让我们来看一下题目中给的样例提示。

样例:

暴力代码90分:

#include<bits/stdc++.h>
using namespace std;
int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	int ch, d, u, maxn=-1;
	cin>>ch>>d>>u;
	for(int i=d;i<=u;i++) maxn=max(maxn,i%ch);
	return cout<<maxn,0;
}

 最后一个u-d=1e9,就死了。

我们来看一下思路:

分析:为了使奖励尽可能多,理想情况就是使得分完之后的剩余糖果数是n-1,因此需要判断能否达到这个理想情况——当区间[L, R]能够完整覆盖一个长度为n的范围,说明一定存在一个数字k,使得k%n=n-1,因此只需要判断L/n是否与R/n一致;如果不能达到这个理想情况,则拿的越多越好,即答案为可以拿到的糖果上限R%n。

总体意思就是,如果在范围内,这个范围就是L~R,就拿最优解,就是n-1,否则就是R%n。

 代码很简单:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int ch, d, u;
	cin>>ch>>d>>u;
	return cout<<(d / ch < u / ch ? ch-1 : u % ch),0;
}

谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值