7-16 修理牧场(25 分)
农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是Li的总和。
但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木头花费15,总花费为35(大于32)。
请编写程序帮助农夫计算将木头锯成N块的最少花费。
输入格式:
输入首先给出正整数N(≤104),表示要将木头锯成N块。第二行给出N个正整数(≤50),表示每段木块的长度。
输出格式:
输出一个整数,即将木头锯成N块的最少花费。
输入样例:
8
4 5 1 2 1 3 1 1
输出样例:
49
这个题可以画一个哈夫曼树,不计算叶子节点,之和就是结果,最优二叉树,用STL中的优先队列可以构造哈夫曼树
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int main()
{
priority_queue<int, vector<int>, greater<int> >q;
int N;
cin>>N;
int number;
for(int i=0;i<N;i++)
{
cin>>number;
q.push(number);
}
int num1;
int num2;
int num3;
int sum=0;
while(true)
{
num1=q.top();
if(q.empty())
break;
q.pop();
num2=q.top();
if(q.empty())
break;
q.pop();
num3=num1+num2;
sum+=num3;
q.push(num3);
}
cout<<sum;
return 0;
}
7-15 寻找大富翁(25 分)
2015年胡润研究院的调查显示,截至2014年9月,个人资产在600万元以上高净值人群达290万人。假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁。
输入格式:
输入首先给出两个正整数N(≤106)和M(≤10),其中N为总人数,M为需要找出的大富翁数;接下来一行给出N个人的个人资产值,以百万元为单位,为不超过长整型范围的整数。数字间以空格分隔。
输出格式:
在一行内按非递增顺序输出资产排前M位的大富翁的个人资产值。数字间以空格分隔,但结尾不得有多余空格。
输入样例:
8 3
8 12 7 3 20 9 5 18
输出样例:
20 18 12
这个题坑爹之处就在于测试点4,总是超时,其实超时并不是因为算法的原因而是,输入函数cin效率太低,只要改cin就行了,这个题同样我用了优先队列做
#include<queue>
#include<iostream>
using namespace std;
priority_queue<int,greater<int> >p;
int main()
{
int number;
int N,M;
cin>>N>>M;
for(int i=0;i<N;i++)
{
cin>>number;
p.push(number);
}
for(int i=0;i<M&&!p.empty();i++)
{
if(i==0)
printf("%d",p.top());
else
printf(" %d",p.top());
p.pop();
}
return 0;
}
7-7 切分表达式——写个tokenizer吧(20 分)
[先说点出题背景]
这个题是为低年级同学、学C语言的同学准备的,因为,对这部分同学,这个题目编写起来略有一点复杂。如果是高年级、学过了正则表达式(Regular Expression)的同学或者学过了Java等OO语言的同学做这个题,应当发现这题比较简单吧。哦,对了,什么是tokenizer?请自行查询解决。反正在此处不应翻译成“令牌解析器”。
[正题]
四则运算表达式由运算数(必定包含数字
,可能包含正或负符号
、小数点
)、运算符(包括+
、-
、*
、/
)以及小括号((
和)
)组成,每个运算数、运算符和括号都是一个token(标记)。现在,对于给定的一个四则运算表达式,请把她的每个token切分出来。题目保证给定的表达式是正确的,不需要做有效性检查。
输入格式:
在一行中给出长度不超过40个字符的表达式,其中没有空格,仅由上文中token的字符组成
输出格式:
依次输出表达式中的tokens,每个token占一行。
输入样例:
32*((2-2)+5)/(-15)
输出样例:
32
*
(
(
2
-
2
)
+
5
)
/
(
-15
)
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
char str[45];
gets(str);
int N=strlen(str);
for(int i=0;i<N;i++)
{
if(str[i]>='0'&&str[i]<='9')
{
if(i+1<N)
{
if(str[i+1]=='.'||(str[i+1]>='0'&&str[i+1]<='9'))
cout<<str[i];
else
cout<<str[i]<<endl;
}
else
cout<<str[i];
}
else if(str[i]=='-')
{
if(i-1>=0&&(str[i-1]>='0'&&str[i-1]<='9'))
cout<<str[i]<<endl;
else
cout<<str[i];
}
else if(str[i]=='.')
cout<<str[i];
else if(str[i]=='+')
{
if(i==0)
cout<<str[i];
else
cout<<str[i]<<endl;
}
else
cout<<str[i]<<endl;
}
return 0;
}
7-6 龟兔赛跑(20 分)
乌龟与兔子进行赛跑,跑场是一个矩型跑道,跑道边可以随地进行休息。乌龟每分钟可以前进3米,兔子每分钟前进9米;兔子嫌乌龟跑得慢,觉得肯定能跑赢乌龟,于是,每跑10分钟回头看一下乌龟,若发现自己超过乌龟,就在路边休息,每次休息30分钟,否则继续跑10分钟;而乌龟非常努力,一直跑,不休息。假定乌龟与兔子在同一起点同一时刻开始起跑,请问T分钟后乌龟和兔子谁跑得快?
输入格式:
输入在一行中给出比赛时间T(分钟)。
输出格式:
在一行中输出比赛的结果:乌龟赢输出@_@
,兔子赢输出^_^
,平局则输出-_-
;后跟1空格,再输出胜利者跑完的距离。
输入样例:
242
输出样例:
@_@ 726
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int T;
cin>>T;
int t;
int t2=0;
for(int t=1;t<=T;t++)
{
t2++;
if(t2%10==0)
{
if(9*t2>3*t)
t+=30;
}
}
if(t2*9-T*3>0)
cout<<"^_^ "<<t2*9;
else if(t2*9-T*3<0)
cout<<"@_@ "<<T*3;
else
cout<<"-_- "<<T*3;
return 0;
}
龟兔赛跑这个题,只要搞清楚,乌龟一直在跑,而兔子不是一直跑,所以循环里面写乌龟跑步时间,兔子的跑动距离只和时间有关系,所以计算时间就可以了