1 装箱问题
输入样例:
8
60 70 80 90 30 40 10 20
输出样例:
60 1
70 2
80 3
90 4
30 1
40 5
10 1
20 2
5
#include<iostream>
using namespace std;
int main(){
int N,i,j;
cin >> N;
int a[N],b[N]={0},c[N]={0};
for(i=0;i<N;i++){
cin >> a[i];
}
for(i=0;i<N;i++)
for(j=0;;j++){
if(a[i]+b[j]<=100){
b[j]+=a[i];
c[i]=j+1;
break;
}
}
for(i=0;i<N;i++)
cout << a[i] << " " << c[i]<<endl;
int max=0;
for(j=0;j<N;j++){
if(c[max]<c[j])
max=j;
}
cout<<c[max];
return 0;
}
2 月饼
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。
注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有 3 种月饼,其库存量分别为 18、15、10 万吨,总售价分别为 75、72、45 亿元。如果市场的最大需求量只有 20 万吨,那么我们最大收益策略应该是卖出全部 15 万吨第 2 种月饼、以及 5 万吨第 3 种月饼,获得 72 + 45/2 = 94.5(亿元)。
输入格式:
每个输入包含一个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N 表示月饼的种类数、以及不超过 500(以万吨为单位)的正整数 D 表示市场最大需求量。随后一行给出 N 个正数表示每种月饼的库存量(以万吨为单位);最后一行给出 N 个正数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。
输出格式:
对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后 2 位。
输入样例:
3 20
18 15 10
75 72 45
输出样例:
94.50
#include<iostream>
#include<algorithm>
using namespace std;
#define max 1000
double x[max]={0};
struct Moon{
float w;
float v;
float p;
}moon[max];
bool comp(Moon a,Moon b){
return a.p>=b.p;
}
void input(int n){
for(int i=1;i<=n;i++){
cin >> moon[i].w;
}
for(int i=1;i<=n;i++){
cin >> moon[i].v;
moon[i].p = moon[i].v/moon[i].w;
}
}
float xs(int N,int D){
float value=0;
for(int i=1;i<=N;i++){
if(D>=moon[i].w){
value+=moon[i].v;
D-=moon[i].w;
}else{
value+=moon[i].p*D;
break;
}
}
return value;
}
int main(){
int N,D;
float TotalValue=0;
cin >> N >> D;
input(N);
sort(moon+1,moon+N+1,comp);
TotalValue = xs(N,D);
printf("%.2f",TotalValue);
}
3 最优合并问题
题目来源:王晓东《算法设计与分析》
给定k 个排好序的序列, 用 2 路合并算法将这k 个序列合并成一个序列。 假设所采用的 2 路合并算法合并 2 个长度分别为m和n的序列需要m+n-1 次比较。试设 计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。 为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。
输入格式:
第一行有 1 个正整数k,表示有 k个待合并序列。 第二行有 k个正整数,表示 k个待合并序列的长度。
输出格式:
输出最多比较次数和最少比较次数。
输入样例:
在这里给出一组输入。例如:
4
5 12 11 2
输出样例:
在这里给出相应的输出。例如:
78 52
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a, int b){
return a > b;
}
int main(){
int N,n;
cin >> N;
list<int> L, p;
for(int i = 0; i < N; i++){
cin >> n;
L.push_back(n);
p.push_back(n);
}
int max = 0, min = 0;
for (int i = 0; i < N - 1; i++){
L.sort();
int mark1 = 0;
for (int i = 0; i < 2; i++){
mark1 += *L.begin();
L.pop_front();
}
min += mark1-1;
L.push_back(mark1);
p.sort(cmp);
int mark2 = 0;
for (int i = 0; i < 2; i++){
mark2 += *p.begin();
p.pop_front();
}
max += mark2-1;
p.push_back(mark2);
}
cout << max << " " << min << endl;
return 0;
}
4 看电影
终于到周末了,明明是特别喜欢看电影。他想在一天内尽量多的看到完整的多部电影。 现在他把他喜欢的电影的播放时间表给你,希望你能帮他合理安排。
输入格式:
输入包含多组测试数据。每组输入的第一行是一个整数n(n<=100),表示明明喜欢的电影的总数。 接下来n行,每行输入两个整数si和ei(1<=i<=n),表示第i个电影的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。 当n=0时,输入结束。
输出格式:
对于每组输入,输出能完整看到的电影的个数。
输入样例:
在这里给出一组输入。例如:
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
输出样例:
在这里给出相应的输出。例如:
5
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct Movie{
int s;
int f;
};
int cmp(Movie &a, Movie &b){
return a.f < b. f;
}
int main(){
int n;
while(cin>>n){
if(n==0){
break;
}
Movie p1[1000];
for(int i = 0; i < n; i ++){
cin>>p1[i].s>>p1[i].f;
}
sort(p1,p1+n,cmp);
int sum = 0;
int num = -1;
for(int i = 0; i < n ;i ++ ){
if(p1[i].s >= num){
sum++;
num = p1[i].f;
}
}
cout<<sum<<endl;
}
}
5 喷水装置
长L米,宽W米的草坪里装有n个浇灌喷头。每个喷头都装在草坪中心线上(离两边各W/2米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。
请问:如果要同时浇灌整块草坪,最少需要打开多少个喷头?
输入格式:
输入包含若干组测试数据。
第一行一个整数T表示数据组数。
每组数据的第一行是整数n、L和W的值,其中n≤10 000。
接下来的n行,每行包含两个整数,给出一个喷头的位置和浇灌半径。
如图1所示的示意图是样例输入的第一组数据所描述的情况。
输出格式:
对每组测试数据输出一个数字,表示要浇灌整块草坪所需喷头数目的最小值。如果所有喷头都打开还不能浇灌整块草坪,则输出-1。
输入样例:
3
8 20 2
5 3
4 1
1 2
7 2
10 2
13 3
16 2
19 4
3 10 1
3 5
9 3
6 1
3 10 1
5 3
1 1
9 1
输出样例:
6
2
-1
数据范围与提示:
对于100%的数据,n≤15000。
#include<iostream>
#include<algorithm>
#include<cmath>
struct Pen{
double left;
double right;
}pen[15000];
int cmp(Pen x,Pen y){
return x.left<y.left; //按照左坐标从小到大排列
}
using namespace std;
int main(){
int N;
cin >> N;
while(N--){
int n;
cin >> n;
double w,h;
cin >> w >> h;
for(int i=0;i<n;i++){
double xi,ri;
cin >> xi >> ri;
double flag;
if(ri>h/2)
flag = sqrt(ri*ri-h*h/4);
else
flag = 0.0;
pen[i].left = xi-flag;
pen[i].right = xi+flag;
}
sort(pen,pen+n,cmp);
int count = 0;
double star =0.0,last; //last记录右交点
for(int i=0;i<n;i++){
if(pen[i].left <= star){
last = pen[i].right;
while(pen[i].left <= star){
last = max(last,pen[i].right);
i++;
if(i == n)
break;
}
star = last; //star记录满足条件的下一个装置的右坐标
i--;
count++;
}
if(star >= w)
break;
}
if(star >= w)
cout << count <<endl;
else
cout << "-1" <<endl;
}
return 0;
}
6 活动选择问题
输入样例:
11
3 5
1 4
12 14
8 12
0 6
8 11
6 10
5 7
3 8
5 9
2 13
输出样例:
4
样例解释:
安排的4个活动为1 4, 5 7, 8 11和12 14。
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct activity{
int s;
int f;
};
int cmp(activity &a, activity &b){
return a.f < b. f;
}
int main(){
int n;
cin >> n;
activity p1[1000];
for(int i = 0; i < n; i ++){
cin>>p1[i].s>>p1[i].f;
}
sort(p1,p1+n,cmp);
int sum = 0;
int num = -1;
for(int i = 0; i < n ;i ++ ){
if(p1[i].s >= num){
sum++;
num = p1[i].f;
}
}
cout<<sum<<endl;
}