一共七个题,A,F图挂了,E是图论现在我不会,G目测是背包,也不会。先把B,C,D题发出来吧··虽然都不难。
B.买酒
Description
众所周知,西瓜是一个很爱喝酒的人。有一天西瓜和朋友去酒楼喝酒,却发现酒楼在大酬宾,活动规则如下。
1.全场只要买酒可以买二送一,买2瓶酒就可以送一瓶酒,买4瓶酒就送两瓶酒。
2.4个空瓶可以换一瓶酒。
3.10个酒瓶盖可以换一瓶酒。
4.拿瓶子和盖子换酒可以享受换二送一的优惠(比如8个空瓶可以换两瓶酒,然后再送一瓶;12个空瓶+10个盖子可以换4瓶酒,再送两瓶),并且换来的酒产生的的瓶盖和空瓶依旧可以继续拿给酒楼换酒。
现在西瓜和朋友们的钱一共有N元, 酒一瓶M元,请问他们最多可以喝多少瓶酒。
Input
题目包含多组输入,EOF结束,数据最多不超过1000组,对于每组数据包含两个数字N,M表示西瓜和朋友们所有钱的数量和一瓶酒的单价,其中1<=N<=1000000, 1<=M<=50
Output
对于每组输入,输出单独一行,表示西瓜和他的朋友们最多能喝到多少瓶酒。
Sample Input
Original Transformed
500 10
50 5
Sample Output
Original Transformed
154
27
Hint
trick较多,请谨慎读题并且思考情况
大致分析:
这个题的trick主要在当兑换总数是奇数时,不要兑换奇数瓶酒。看是那个部分是奇数,这次少换一瓶。看之后能不能凑成整数再换。但当兑换数是1的时候例外,单独考虑即可。
代码:
#include<iostream>
using namespace std;
//变量名字起的很随意
int main()
{
int N,M;
while(cin>>N>>M)
{
int ans=0;
int number_glass=N/M;
int number_cap=N/M;
ans=number_cap/2+number_cap;
number_cap=ans;
number_glass=ans;
while(number_cap>=10||number_glass>=4)
{
int change_cap=number_cap/10;
int chang_glass=number_glass/4;
int change=change_cap+chang_glass;
if ( ( change_cap + chang_glass )%2 == 0|| change==1){//判断是否是奇数部分,1的时候单独考虑
int change_number=change/2+change;
ans+=change_number;
number_cap=number_cap%10+change_number;
number_glass=number_glass%4+change_number;
}else {
int change_number=(change-1)/2+change-1;
ans+=change_number;
if(change_cap%2==1){
number_cap=number_cap%10+change_number+10;
number_glass=number_glass%4+change_number;
}else {
number_cap=number_cap%10+change_number;
number_glass=number_glass%4+change_number+4;
}
}
}
cout<<ans<<endl;
}
return 0;
}
C.西瓜理发记(一)
Description
某天,西瓜决心皈依勺林寺,于是来到安大门口的理发店,准备剃一个光头。
然而理发店有很多人排队,西瓜想知道他大概还需要排队排多久。
假设一位男生需要8分钟,一位女生需要12分钟。
Input
测试数据包括多组
每组数据包含一个字符串s,0<|s|<=2000
字符串只包含字符’M’,’W’,’O’
M表示男生,W表示女生,O表示西瓜
在字符串中的位置越左表示在队伍当中越靠前
保证每个字符串不为空,且O只有一个
Output
对应每组数据输出一个整数,表示西瓜大概需要等待的分钟数。
Sample Input
Original Transformed
MWWWO
O
Sample Output
Original Transformed
44
0
纯水题,没啥解释的。
代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[2000];
while(cin>>str)
{
int time=0;
int len=strlen(str);
for(int i=0;i<len;++i){
if(str[i]=='W')
time+=12;
else if(str[i]=='M')
time+=8;
else
break;
}
cout<<time<<endl;
}
return 0;
}
D.西瓜理发记(二)
Description
剃完光头后,西瓜表示非常开心,于是直接骑上自行车去往勺林寺。
等骑到勺林寺的时候,头发已经都长出来了,于是西瓜决定在附近的理发店再剃一次。
然而这里的理发店老板WzyJerry表示正在做ACM练习,没空给他理发。
西瓜决定帮助老板AK。
题目是这样的:
你现在有一个培养盒,盒中没有细菌
每天早上,你可以向盒中放入一个细菌
每天晚上,一个细菌会分裂成两个。
求如果你想在将来的某天使盒中恰好有n个细菌,你最少要向盒中放入几个细菌
Input
输入数据包含多组
每组一个整数n(1≤n ≤10^9)
Output
每组数据输出一个整数x,表示最少需要放入的细菌个数
Sample Input
Original Transformed
5
1
Sample Output
Original Transformed
2
1
大致思路
每天早上有两个选择:放一个或者不放。当N为奇数时,说明早上放细菌了,反之就是没有放。这样代码就很好写了。
代码:
#include<iostream>
using namespace std;
int f(int n,int Count)
{
if(n==0)
return Count;
else if(n == 1)
return Count+1;
if(n%2)
return f(n-1,Count+1);
else
return f(n/2,Count);
}
int main()
{
int n;
while(cin>>n)
{
int Count=0;
cout<<f(n,Count)<<endl;
}
return 0;
}