1.买不到的数目
方案一:打表找规律(超时)
#include <iostream>
using namespace std;
//给定一个m,是否能用p和q凑出来
bool 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;
}
int main()
{
int p,q;
cin >> p >> q;
int res = 0;
for(int i = 1; i <= 1000;i ++)
{
if(!dfs(i,p,q)) res = i;
}
cout << res << endl;
return 0;
}
方案二:数论
结论:
如果 a , b a,b a,b 均是正整数且互质,那么由 a x + b y , x ≥ 0 , y ≥ 0 ax+by,x≥0,y≥0 ax+by,x≥0,y≥0 不能凑出的最大数是
a b − a − b ab−a−b ab−a−b。
下面给出证明:
首先证明
a
b
−
a
−
b
ab−a−b
ab−a−b 不能被
a
x
+
b
x
,
x
≥
0
,
y
≥
0
ax+bx,x≥0,y≥0
ax+bx,x≥0,y≥0表示出。
反正法,假设
a
b
−
a
−
b
=
a
x
+
b
y
ab−a−b=ax+by
ab−a−b=ax+by,那么
a
b
=
a
(
x
+
1
)
+
b
(
y
+
1
)
ab=a(x+1)+b(y+1)
ab=a(x+1)+b(y+1),由于
a
∣
a
b
,
a
∣
a
(
x
+
1
)
a|ab,a|a(x+1)
a∣ab,a∣a(x+1),所以
a
∣
b
(
y
+
1
)
a|b(y+1)
a∣b(y+1),由于
a
,
b
a,b
a,b 互质,所以
a
∣
(
y
+
1
)
a|(y+1)
a∣(y+1),由于
y
≥
0
y≥0
y≥0,所以
a
<
=
y
+
1
a<=y+1
a<=y+1,所以
b
(
y
+
1
)
≥
a
b
b(y+1)≥ab
b(y+1)≥ab。同理可得
a
(
x
+
1
)
≥
a
b
a(x+1)≥ab
a(x+1)≥ab,所以
a
(
x
+
1
)
+
b
(
y
+
1
)
≥
2
a
b
>
a
b
a(x+1)+b(y+1)≥2ab>ab
a(x+1)+b(y+1)≥2ab>ab,矛盾。
证明 a b − a − b + d , d > 0 ab−a−b+d,d>0 ab−a−b+d,d>0 一定可以表示成 a x + b y , x , y ≥ 0 ax+by,x,y≥0 ax+by,x,y≥0的形式,可以参考 这篇博客。
时间复杂度分析
计算
a
b
−
a
−
b
ab−a−b
ab−a−b的时间复杂度是
O
(
1
)
O(1)
O(1)。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int main()
{
LL a, b;
cin >> a >> b;
cout << a * b - a - b << endl;
return 0;
}
2.蚂蚁感冒
小结
代码
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 55;
int n;
int x[N];
int main()
{
cin >> n;
for(int i = 0; i < n;i++) scanf("%d",&x[i]);
//左边向右走用left
//右边向左走用right
int left = 0,right = 0;
for(int i = 0;i < n;i++)
{
if(abs(x[i]) < abs(x[0]) && x[i] > 0) left++;
else if(abs(x[i]) > abs(x[0]) && x[i] < 0) right++;
}
if(x[0] > 0 && right == 0 || x[0] < 0 && left == 0) printf("%d",1);
else printf("%d",left + right + 1);
return 0;
}
3.饮料换购
每换一次,少两个盖,多一瓶饮料
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int n;
cin>>n;
int res=n;
while(n>=3)
{
n-=2; //换一瓶饮料,少俩盖
res++;
}
cout<<res;
}