ACDaily 3

本文最后更新于:3 个月前

数学与简单DP

数学(根据例题讲解)

买不到的数

小明开了一家糖果店。

他别出心裁:把水果糖包成4颗一包和7颗一包的两种。

糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。

当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。

大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

输入格式

两个正整数 n,m,表示每种包装中糖的颗数。

输出格式

一个正整数,表示最大不能买到的糖数。

数据范围

2≤n,m≤1000,
保证数据一定有解。

输入样例:

4 7

输出样例:

17

题解

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

using namespace std;

int main()
{
int n, m, res = 0;
cin >> n >> m;
res = (m-1)*(n-1) - 1;
cout << res;
return 0;
}
  1. 找最大公约数,如哦不是最大公约数的倍数则无解

  2. 打表找规律,裴蜀定理,获得公式,具体公式推导可以参考AcWing525

    • 最后进行公式输出即可

    • 递归能够确定终点,需要由终点进行反推,来判断深搜是否成立,中间进行的递归是为了确定深搜中不同的方向(与二叉树相似)

    • 注意这仅仅是打表

    • 最终还要根据数据表内的信息来寻找规律

感冒的蚂蚁

长 100 厘米的细长直杆子上有 n 只蚂蚁。

它们的头有的朝左,有的朝右。

每只蚂蚁都只能沿着杆子向前爬,速度是 1 厘米/秒。

当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。

这些蚂蚁中,有 1 只蚂蚁感冒了。

并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。

请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。

输入格式

第一行输入一个整数 n, 表示蚂蚁的总数。

接着的一行是 n 个用空格分开的整数 Xi, Xi 的绝对值表示蚂蚁离开杆子左边端点的距离。

正值表示头朝右,负值表示头朝左,数据中不会出现 0 值,也不会出现两只蚂蚁占用同一位置。

其中,第一个数据代表的蚂蚁感冒了。

输出格式

输出1个整数,表示最后感冒蚂蚁的数目。

数据范围

1<n<50,
0<|Xi|<100

输入样例1:

3
5 -2 8

输出样例1:

3

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 60;
int a[N];

int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++) cin >> a[i];

int right = 0, left = 0;
for(int i = 0; i < n; i++)
{
if(abs(a[i]) < abs(a[0]) && a[i] > 0) left++;
if(abs(a[i]) > abs(a[0]) && a[i] < 0) right++;
}

if(a[0] > 0 && right == 0 || a[0] < 0 && left == 0) cout << 1 << endl;
else cout << left+right+1 << endl;
return 0;
}
  1. 做简单的魂穿假设,蚂蚁之间碰撞之时,方向不改变,但个体的性质发生变化
  2. 分析
    • 首先以感染源蚂蚁为核心,按是否可能被感染将左右两边的蚂蚁进行分类
    • 判断感染源蚂蚁的行进方向,进行最终被感染蚂蚁的计算

饮料换购

乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。

请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的 n 瓶饮料,最后他一共能喝到多少瓶饮料。

输入格式

输入一个整数 n,表示初始买入的饮料数量。

输出格式

输出一个整数,表示一共能够喝到的饮料数量。

数据范围

0<n<10000

输入样例:

100

输出样例:

149

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int main()
{
int n;
cin >> n;
int res = n;
while(n >= 3)
{
res += n/3;
n = (n/3) + (n%3);
}

cout << res;
return 0;
}
  1. 注意这是一个上下取整问题

  2. 注意每次都要尽可能将瓶盖换掉,不到多余


本文作者: waitingFor
本文链接: http://example.com/2022/03/03/ACDaily/ACDaily-3/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!