4-01 一辆虚拟汽车在加满油之后可以行驶 n km。旅途中有 k 个加油站。设计一个有效算法,使得沿途加油的次数最少。终端输入正整数 n 和 k,表示汽车加满油后可行驶 n km,且旅途中有 k 个加油站。接下来输入 k+1个整数,表示第 k 个加油站与第 k-1个加油站之间的距离。第 0 个加油站表示出发地,汽车已加满油。第 k+1个加油站表示目的地。
在到达某个加油站时判断能否到达下一个加油站。
#include <iostream>
using namespace std;
const int N = 20;
int main()
{
int n, k;
cin >> n;
cin >> k;
int a[N];
int i;
for (i = 0; i <= n; i++)
{
cin >> a[i];
}
int sum = a[0];
int count = 0;
for (i = 0; i <= k; i++)
{
if ((sum + a[i]) <= n)
{
sum += a[i];
}
else if (a[i] > n)
{
cout << "error" << endl;
return 0;
}
else
{
count++;
sum = a[i];//更新距离
}
}
cout<<count;
return 0;
}
4-02 设x1,x2,…,xn是实直线上的n 个点。用固定长度的闭区间覆盖这n 个点,至少需要多少个这样的固定长度闭区间?对于给定的实直线上的n个点和闭区间的长度k,设计解此问题的有效算法,计算覆盖点集的最少区间数。
先对n个点排序,第一个点为起点,长度为k的闭区间进行覆盖,接下来遍历每个点时,判断能否与前面的点覆盖在一个区间长度内。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n, k;
cout << "输入点的数量和区间长度" << endl;
cin >> n >> k;
vector<int> point(n);
cout << "输入点的位置" << endl;
for (int i = 0; i < n; i++)
{
cin >> point[i];
}
sort(point.begin(), point.end());
int a = point[0];
int count = 1;
for (int i = 1; i < n; i++)
{
if (a + k < point[i])
{
count++;
a = point[i];
}
}
cout <<"需要"<< count <<"个区间"<< endl;
return 0;
}
4-03 【数列极差】问题描述:在黑板上写了N个正整数作成的一个数列,进行如下操作:每一次擦去其中的两个数a和b,然后在数列中加入一个数a*b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的max,最小的为min,则该数列的极差定义为M=max-min。
每次从最小的两个数相乘后的数值放到原来的数组中可能需要重新顺序,所以再用一个排序使新的数组变得有序,依次循环得到最大值。而求最小值时前边两个最大的数乘起来的数不可能会比后边小的数还要小,就不用每次排序。
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100;
int a[N];
int b[N];
int cmp(int c, int d) {
return c >= d;
}
int main() {
int n;
while (cin >> n && n) {
for (int i = 0; i < n; i++) {
cin >> a[i];
b[i] = a[i];
}
//先升序排列
sort(a, a + n);
for (int i = 1; i < n; i++) {
a[i] = a[i] * a[i - 1] + 1;//从小到大排完序之后,先从前边最小的两个数相乘然后存放到数组里
sort(a + i, a + n);
}
int max = a[n - 1];
sort(b, b + n, cmp);
for (int i = 1; i < n; i++) {
b[i] = b[i - 1] * b[i] + 1;
}
int min = b[n - 1];
cout << max - min << endl;
}
return 0;
}