AcWing 1205. 买不到的数目
小明开了一家糖果店。
他别出心裁:把水果糖包成4颗一包和7颗一包的两种。
糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。
当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。
大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入格式
两个正整数 n,m,表示每种包装中糖的颗数。
输出格式
一个正整数,表示最大不能买到的糖数。
数据范围
2≤n,m≤1000,
保证数据一定有解。
输入样例:
4 7
输出样例:
17
题意:给出m n两个数,求解不能用几个m和几个n所构成的最大值。
例如4和7所不能组成的最大值为17,大于17的数都可以由这两个数组成。
从数论开始的题就有点难顶了,其中会涉及到很多数学公式类似奥数的问题,可惜本混子并没有学过奥数,如果是第一次遇到的话只能现场嗯做了。
在不确定公式的情况下,一种思路就是打表找规律,虽然笨比但是有效,先敲一个打表代码,参考y总
import java.io.*;
import java.util.*;
public class Main {
static Scanner tab = new Scanner(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 100010;
public static boolean dfs(int m, int p, int q) {
if (m == 0)
return true;
if (m >= p && dfs(m - p, p, q))
return true;
if (m >= q && dfs(m - q, p, q))
return true;
return false;
}
public static void main(String[] args) throws IOException {
while (tab.hasNext()) {
int p = tab.nextInt();
int q = tab.nextInt();
int res = 0;
for (int i = 1; i <= 1000; i++) {
if (!dfs(i, p, q))
res = i;
}
System.out.println(res);
}
}
}
注意的是一些基本的定理还是要知道的,比如在此题中,如果gcd(p,q)>1,换句话说如果p和q非互质,那么这对数是一定无解的,他们不能构成的数是无穷大的
这里由于p,q<=1000,就将取值范围暂定在1000以内,稳妥起见使用几个较小的数,查找出规律即可
以p q为例,先使一个值为定值,令p=3,更改q的值,记录res
p q res
3 2 1
3 4 5
3 5 7
3 7 11
3 8 13
3 10 17
接下来就是找规律环节,只能靠灵性了
当p=3时,计算出规律为res=2*q-3
令p=4
p q res
4 3 5
4 5 11
4 7 17
4 9 23
4 11 29
4 13 35
规律res=3*q-4
继续推算的话令p=5时公式应当是
res=4*q-5
总结以上公式,推算出最终式
res=(p-1)*q-p
当推出这个公式后就可以使用O(1)的时间来解出结果
这同样是一个定理
如果 a,b 均是正整数且互质
那么由 ax+by,x≥0,y≥0ax+by,x≥0,y≥0 不能凑出的最大数是(a−1)(b−1)−1。
最终代码
import java.io.*;
import java.util.*;
public class Main {
static Scanner tab = new Scanner(System.in);
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N = 100010;
public static void main(String[] args) throws IOException {
int n=tab.nextInt();
int m=tab.nextInt();
System.out.println((n-1)*(m-1)-1);
}
}
所以涉及数论的题要是靠现场推理出来实在是浪费时间,还是要平时积累公式越多越好