目录
买不到的数目(第四届蓝桥杯省赛C++A组,第四届蓝桥杯省赛JAVAC组)
饮料换购(第六届蓝桥杯省赛C++A/C组,第六届蓝桥杯省赛JAVAB组)
买不到的数目(第四届蓝桥杯省赛C++A组,第四届蓝桥杯省赛JAVAC组)
小明开了一家糖果店。
他别出心裁:把水果糖包成4颗一包和7颗一包的两种。
糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。
当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。
大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入格式
两个正整数 n,mn,m,表示每种包装中糖的颗数。
输出格式
一个正整数,表示最大不能买到的糖数。
数据范围
2≤n,m≤10002≤n,m≤1000,
保证数据一定有解。
输入样例:
4 7
输出样例:
17
#include<iostream>
using namespace std;
int p,q;
int main()
{
cin>>p>>q;
cout<<p*q-p-q<<endl;//(p-1)(q-1)-1 打表找规律
return 0;
}
蚂蚁感冒(第五届蓝桥杯省赛C++A/B组)
长 100100 厘米的细长直杆子上有 nn 只蚂蚁。
它们的头有的朝左,有的朝右。
每只蚂蚁都只能沿着杆子向前爬,速度是 11 厘米/秒。
当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。
这些蚂蚁中,有 11 只蚂蚁感冒了。
并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。
请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
输入格式
第一行输入一个整数 nn, 表示蚂蚁的总数。
接着的一行是 nn 个用空格分开的整数 XiXi, XiXi 的绝对值表示蚂蚁离开杆子左边端点的距离。
正值表示头朝右,负值表示头朝左,数据中不会出现 00 值,也不会出现两只蚂蚁占用同一位置。
其中,第一个数据代表的蚂蚁感冒了。
输出格式
输出1个整数,表示最后感冒蚂蚁的数目。
数据范围
1<n<501<n<50,
0<|Xi|<1000<|Xi|<100
输入样例1:
3
5 -2 8
输出样例1:
1
输入样例2:
5
-10 8 -20 12 25
输出样例2:
3
#include<iostream>
using namespace std;
const int N = 55;
int n;
int x[N];
//本题重要思想 两只蚂蚁碰撞掉头 可以等价于两只蚂蚁穿过
//在转换思想后:在第一只蚂蚁左边的往左的蚂蚁一定不会被感染 在第一只蚂蚁右边往右走的蚂蚁一定不会被感染
/* 第一只蚂蚁向右时
在第一只蚂蚁右边往左的蚂蚁一定会被感染 如果第一只蚂蚁右边向左的蚂蚁存在的话 那么第一只蚂蚁左边向右走的蚂蚁一定被感染
如果第一只蚂蚁右边向左的蚂蚁不存在的话 那么第一只蚂蚁左边向右走的蚂蚁不会被感染
*/
/*第一只蚂蚁向左时
在第一只蚂蚁左边往右走的蚂蚁一定会被感染 如果第一只蚂蚁左边向右的蚂蚁存在的话 那么第一只蚂蚁右边向左走的蚂蚁一定被感染
如果第一只蚂蚁左边向右的蚂蚁不存在的话 那么第一只蚂蚁右边向左走的蚂蚁一定不会被感染
*/
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>x[i];
int l=0,r=0;//表示在第一只蚂蚁左边从左往右走的蚂蚁 和第一只蚂蚁右边从右往左走的蚂蚁
for(int i=1;i<n;i++)
{
if(abs(x[i])>abs(x[0])&&x[i]<0)r++;//在第一只蚂蚁右边从右往左走的蚂蚁
else if(abs(x[i])<abs(x[0])&&x[i]>0)l++;//在第一只蚂蚁左边从左往右走的蚂蚁
}
//第一只蚂蚁向右时,第一只蚂蚁右边向左的蚂蚁不存在的话 或者 第一只蚂蚁向左时 如果第一只蚂蚁左边向右的蚂蚁不存在的 就第一只蚂蚁被感染
if((x[0]>0&&r==0)||(x[0]<0&&l==0))cout<<1<<endl;
else cout<<l+r+1<<endl;// 左边向右的蚂蚁 + 右边向左的蚂蚁 +第一只蚂蚁
return 0;
}
饮料换购(第六届蓝桥杯省赛C++A/C组,第六届蓝桥杯省赛JAVAB组)
有 NN 件物品和一个容量是 VV 的背包。每件物品只能使用一次。
第 ii 件物品的体积是 vivi,价值是 wiwi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,VN,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 NN 行,每行两个整数 vi,wivi,wi,用空格隔开,分别表示第 ii 件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤10000<N,V≤1000
0<vi,wi≤10000<vi,wi≤1000
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
//简单模拟题
int main()
{
cin>>n;
int ans=n;//ans表示答案 首先先将n瓶加入答案
while(n>=3)//当n大于等于3的时候 表示还可以再继续兑换
{
int t=n/3;//表示可以最多兑换的瓶数
n=n-(t*3)+t;//n减去消耗的饮料数 在加上兑换来的饮料
ans+=t;//答案加上兑换来的饮料
}
cout<<ans<<endl;
return 0;
}
背包问题
有 NN 件物品和一个容量是 VV 的背包。每件物品只能使用一次。
第 ii 件物品的体积是 vivi,价值是 wiwi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,VN,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 NN 行,每行两个整数 vi,wivi,wi,用空格隔开,分别表示第 ii 件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤10000<N,V≤1000
0<vi,wi≤10000<vi,wi≤1000
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int dp[N][N];//dp[i][j]表示前i个物品 总体积是j最大价值
int v[N],w[N];//v 体积 w 价值
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
dp[i][j]=dp[i-1][j];//不选第i个物品 前i-1个物品最大价值
if(j>=v[i])dp[i][j]=max(dp[i][j],dp[i-1][j-v[i]]+w[i]);//当体积大于v[i] 可以选择选第i个物品
}
}
int ans=0;
for(int i=0;i<=m;i++)ans=max(ans,dp[n][i]);//获取最大的答案
cout<<dp[n][m]<<endl;
return 0;
}