1001搬砖
Problem Description
小明现在是人见人爱,花见花开的高富帅,整天沉浸在美女环绕的笙歌妙舞当中。但是人们有所不知,春风得意的小明也曾有着一段艰苦的奋斗史。
那时的小明还没剪去长发,没有信用卡没有她,没有24小时热水的家,可当初的小明是那么快乐,尽管甚至没有一把破木吉他…
之所以快乐,是因为那时的小明心怀逆袭梦想。有一天,小明为了给他心目中的女神买生日礼物,来到了某建筑工地搬砖挣钱。就在这个时候,工地上又运来了一卡车的砖,包工头让小明把卡车卸下来的那堆砖分成一块一块的(要求任何2块转都要分开)。作为资深搬运工,小明总是每次将一堆砖分为两堆,这时候,所消耗的体力是分完之后两堆砖数目的差值。
现在,已知卡车运来的砖的数目,请告诉小明最少要花费多少体力才能完成包工头所要求的任务呢?
Input
输入数据第一行是一个正整数T(T<=100),表示有T组测试数据。
接下来T行每行一个正整数N(N<=10000000),表示卡车运来的砖块的数目。
Output
对于每组数据,请输出小明完成任务所需的最少体力数。
Sample Input
4
5
Sample Output
0
2
题意概述
把一个数a分成b+c,需要消耗abs(b-c)的精力。现需要把一个数n无限次数的分解成n个1,问:最少需要消耗多少精力?
题目分析
首先考虑到对于1,不需要分解,消耗为0。
对于2可以分解为1+1,消耗为0。
对于3可以分解为1+2,消耗为1的消耗+2的消耗+abs(1-2)。
……
动态规划:
设f(n)为分解n时的最小消耗,当n为偶数时,f(n)=2*f(n/2);当n为基数时,f(n)=f(n/2)+f(n/2+1)+1。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define INF 0x7ffffff
#define LOCAL
using namespace std;
int ans[10000001];
int main(){
#ifdef LOCAL
freopen("input.in","r",stdin);
#endif // LOCAL
int t;
for(int i=0;i<10000001;i++){
ans[i] = 0;
}
ans[1] = 0;
ans[2] = 0;
for(int i=3;i<10000001;i++){
if(i%2!=0) ans[i] = ans[i/2]+ans[i/2+1]+1;
else ans[i] = 2*ans[i/2];
}
cin>>t;
while(t--){
int a;
cin>>a;
cout<<ans[a]<<endl;
}
return 0;
}
or
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define INF 0x7ffffff
#define LOCAL
using namespace std;
int f(int n){
if(n==1||n==2){
return 0;
}
if(n%2)
return f(n/2)+f(n/2+1)+1;
else
return 2*f(n/2);
}
int main(){
#ifdef LOCAL
freopen("input.in","r",stdin);
#endif // LOCA
int t;
cin>>t;
while(t--){
int a;
cin>>a;
cout<<f(a)<<endl;
}
return 0;
}
1002投币洗衣机
Problem Description
如今大学生的生活条件越来越好了,近期,内蒙某高校在每个寝室楼都添置了一台投币洗衣机。
小明作为经常参加训练的ACM队员,非常忙(Lan)碌(Duo),当然非常乐意把衣服丢给洗衣机解决啦。根据要洗的衣服数量,投币洗衣机每次需要投入2-4 枚硬币。
小明是一个非常容易出汗的男生,夏天就要到了,每天都要洗澡,所以也就有大量衣服需要洗。
小明是这么制定投币洗衣机计划的:当屯积的衣服数量大于等于a且小于b的时候,他就会马上全部拿去给洗衣机洗,并且投入2枚硬币;当屯积的衣服数量大于等于b且小于c的时候,他就会马上全部拿去给洗衣机洗,并且投入3枚硬币;当屯积的衣服数量大于等于c的时候,他就会马上全部拿去给洗衣机洗,并且投入4枚硬币。其他细节见样例。
现在知道,小明过去n 天每天换下的衣服数量v件,需要你帮忙计算出小明在过去这段时间洗衣服一共花了多少钱。
Input
输入包含多组测试数据。
每组数据第一行是4个正整数 n (1<=n<=10000) 、a 、b 、c (1<=a
题意概述
简单的条件判断
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define INF 0x7ffffff
#define LOCAL
using namespace std;
int arr[10001];
int main(){
#ifdef LOCAL
freopen("input.in","r",stdin);
#endif // LOCAL
int n,a,b,c;
while(cin>>n>>a>>b>>c){
for(int i=1;i<=n;i++){
cin>>arr[i];
}
int totle = 0;
int money = 0;
for(int i=1;i<=n;i++){
totle+=arr[i];
if(totle>=a&&totle<b){
money+=2;
totle = 0;
}else if(totle>=b&&totle<c){
money+=3;
totle = 0;
}else if(totle>=c){
money+=4;
totle = 0;
}else{
continue;
}
}
cout<<money<<endl;
}
return 0;
}
1003掷色子
Problem Description
Nias与Ains都特别喜欢玩骰子,而且都自以为比对方玩得更溜。
终于有一天,他们决定用骰子来一决高下!
一般的骰子玩法已经不足以体现他们的水平了,于是他们自创了一套玩法来PK:
首先,每人掷3个骰子;之后,可以选择其中一个骰子重新掷(当然也可以放弃这一步),最后,比较投掷结果的大小,结果大的那方获胜,一样的话为平局。
大小比较规则为:
三个一样数字的骰子称为三条;两个一样数字的骰子称为对子;只有一个数字的骰子成为散牌。三条>对子>散牌。当双方结果都为三条时,直接比较三条数字的大小;都有对子时,先比较对子数字的大小,若相同,再比较剩下的骰子的数字的大小;都只有散牌时,先比较最大的数字的大小,若相同,再比较次大的数字的大小,还相同,最后比较最小的数字的大小。
现在Nias已经投了3个骰子,还剩一次机会可以选择其中一个骰子重新投(或不选),而且他已经知道了Ains的最后投掷结果,求Nias获胜的概率有多大。
Input
输入数据第一行为一个整数T,表示有T组测试数据。
接下来T行,每行6个1~6的整数,前三个表示Nias第一次的投掷结果,后三个表示Aias最终的投掷结果。
Output
请输出Nias获胜的概率,结果保留3位小数,每组输出占一行。
Sample Input
4
2 3 5 3 3 4
3 3 1 2 2 2
6 2 1 5 4 3
1 2 3 4 4 1
Sample Output
0.333
0.167
1.000
0.000
题意概述
甲乙两人各有三个色子,掷完后,甲可以选择任意选择一个色子重新掷或不掷。问甲胜的概率有多大?(其中三条大于对子大于散牌)
题意分析
模拟题,如果甲本来就大于乙,则胜率为1.000;若甲本来不大于乙,则对三个色子分别模拟投掷,每个模拟投掷的点数为1-6,对每种可能的结果进行判断是否能胜乙。取三个色子中胜率最大的那个。
代码
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
int judge_type(int *a){
sort(a,a+3);
if(a[0]==a[2])
return 3;
else if(a[0]==a[1]||a[1]==a[2])
return 2;
else
return 1;
}
bool judge_win(int *a,int *b){
int a_type = judge_type(a);
int b_type = judge_type(b);
if(a_type==b_type){
sort(a,a+3);
sort(b,b+3);
int a_value = a[2]*100+a[1]*10+a[0];
int b_value = b[2]*100+b[1]*10+b[0];
if(a_type!=2){
return a_value>b_value;
}else{
int a_double= a[1];
int a_single = a[0]==a[1]?a[2]:a[0];
int b_double = b[1];
int b_single = b[0]==b[1]?b[2]:b[0];
if(a_double>b_double||(a_double==b_double&&a_single>b_single)) return true;
else return false;
}
}else{
return a_type>b_type;
}
}
int nias[3],ains[3];
int main()
{
int t;
cin>>t;
while(t--){
scanf("%d%d%d%d%d%d",nias,nias+1,nias+2,ains,ains+1,ains+2);
if(judge_win(nias,ains)){
printf("1.000\n");
}else{
double ans = 0;
int p[3];
for(int i=0;i<3;i++){
int win =0 ;
for(int j=1;j<=6;j++){
p[0] = nias[(i+1)%3];
p[1] = nias[(i+2)%3];
p[2] = j;
if(judge_win(p,ains))
win++;
}
ans = max(ans,1.0*win/6.0);
}
printf("%.3lf\n",ans);
}
}
return 0;
}