山东大学计算机科学与技术学院程序设计思维与实践作业
山大程序设计思维与实践作业
sdu程序设计思维与实践
山东大学程序设计思维实践作业H4
山大程序设计思维实践作业H4
山东大学程序设计思维与实践
week4-贪心和二分
相关资料:GitHub
B : 截绳子
题目描述
有 n 段绳子,长短不一。现在要从中截出 k 段长度相同的绳子。当然,一段绳子可以截出来多段绳子。截出来的绳子最长是多少?
输入格式
第一行两个整数 n 和 k (1≤n,k≤105)
接下来 n 行,每行有一个整数 ai (1≤ai≤107),代表每根绳子的长度
输出格式
一个数,代表最长长度。相对误差或绝对误差不超过 10−6
测试样例
样例 1
输入:
4 11
802
743
457
539
输出:
200.5
#include<bits/stdc++.h>
using namespace std;
int main()
{
double es = 1e-8;
int n, k;
cin>>n>>k;
double x[n];
double sum = 0, len = 0, rad;
for (int i = 1; i <= n; i++){
cin>>x[i];
sum += x[i];
len = max(len, x[i] / k);
}
rad = sum / k;
while(fabs(rad - len) > es){
double mid = (rad + len) / 2;
int num = 0;
for (int i = 1; i <= n; i++){
num += x[i] / mid;
}
if(num >= k){
len = mid;
}else{
rad = mid;
}
}
cout<<len;
return 0;
}
C : 复印机
题目描述
有一份原稿,需要复印出 n 份复印件出来。有两台复印机,一台可以每 x 秒复印出一份,另一台可以每 y 秒复印出一份。现在想知道,至少需要多久才能复印完成?
提示:复印件也可以被复印
输入格式
一行三个整数 n,x 和 y (1≤n≤2×108,1≤x,y≤10)
输出格式
一个整数,代表复印 n 份的最短时间
测试样例
样例 1
输入:
4 1 1
输出:
3
样例 2
输入:
5 1 2
输出:
4
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,x,y,m;
cin>>n;
cin>>x;
cin>>y;
if(x>y){
m = x;
x = y;
y = m;
}
int a = x,xx=0,yy=0,sum=1;
if(x == y){
int t = (ceil((n-1) / 2.0 )+ 1) * x;
cout<<t<<endl;
return 0;
}
while(sum < n){
yy++;
xx++;
if(xx==x){
sum++;
xx = 0;
}
if(sum >= n)
{
a++;
break;
}
if(yy==y){
sum++;
yy = 0;
}
a++;
}
cout<<a;
return 0;
}
D : 商店
题目描述
一条街上有 n 个商店,在第 i 个商店,可以以 ai 的价格买入一个商品,也可以以 ai 的价格卖出一个商品。商品很沉,最多只能同时拿着 1 个商品在街上走。现在按照给定顺序依次访问所有商店,那么,最大收益是多少?在获得最大收益的前提下,最少交易次数是多少?
输入格式
第一行一个整数 T (1≤T≤5),代表测试用例个数
下面 T 组数据,其中每一组数据都占两行,其中
第一行一个整数 n (1≤n≤105),代表商店个数
下面一行 n 个整数,其中第 i 个数为 ai (0≤ai<2147483648),代表在第 i 个商店可以买入或卖出商品的价格
输出格式
对于每个例子,输出一行两个整数,分别代表最大收益和获得最大收益的前提下最少的交易次数
测试样例
样例 1
输入:
1
5
9 10 7 6 8
输出:
3 4
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
cin>>T;
for (int t = 0; t < T; ++t) {
long long n;
cin>>n;
int a[n+1];
for (int i = 1; i <=n ; ++i) {
cin>>a[i];
}
long long qian=0;
long long cnt=0;
int fst=1;
int lst=1;
for (int i = 2; i <=n ; ++i) {
if(a[i]>=a[lst]) {
lst = i;
if(lst==n)
{
if(a[lst]>a[fst])
{
qian+=a[lst]-a[fst];
cnt+=2;
}
}
else if(a[lst+1]<a[lst]&&a[lst]>a[fst])
{
qian+=a[lst]-a[fst];
cnt+=2;
fst=lst+1;
lst=lst+1;
}
}
if(a[i]<a[fst]) {
fst = i;
lst=i;
}
}
cout<<qian<<' '<<cnt<<endl;
}
}
E : 游戏
题目描述
Alice 和 Bob 在做游戏。Alice 写下了 n 个不同的数字,又选取了数字 K。Alice 让 Bob 进行一些操作,每次操作如下:
- 选取两个整数 x,y ,它们的差值不超过 K ,即 ∣x−y∣<=K
- 删除它们中较小的数字
Bob 的任务是,尽可能多的进行这样的操作。当然 Bob 有可能一次操作都做不了。那么,Bob 最多可以进行多少次操作?
输入格式
第一行两个整数 n,K (1≤n≤105,1≤K≤1012)
下面一行 n 个整数,其中第 i 个数为 ai (0≤ai≤1012),代表 Alice 写下的数字
输出格式
输出一个整数,代表 Bob 最多可以进行的操作次数
测试样例
样例 1
输入:
5 1
3 7 4 1 5
输出:
2
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
long long K;
cin>>K;
vector<long long> z(n);
for(auto &i:z)
cin>>i;
sort(z.begin(),z.end());
int operation=0;
for(int i=0;i<n-1;i++){
if(z[i+1]-z[i]<=K){
operation++;
}
}
cout<<operation<<endl;
return 0;
}