习题课,无知识点
数列极差问题
题目描述
在黑板上写了N个正整数组成的一个数列,进行如下操作: 每次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上 剩下一个数,在所有按这种操作方式最后得到的数中,最大的为max,最小的为min, 则该数列的极差定义为M=max-min。
请你编程,对于给定的数列,计算极差。
输入描述
输入包含多个测试集。每个测试集的第一个数N表示 正整数序列长度(0<=N<=50000),随后是N个正整数。N为0表示输入结束
输出描述
每个结果一行
样例
输入
3
1
2
3
0
输出
2
代码
cpp
#include<iostream>
#include<queue>
using namespace std;
int n,a[50005];
long long c,j;
int main(){
while(cin>>n&&n!=0){
priority_queue<int>q;
priority_queue<int,vector<int>,greater<int> >b;
for(int i=1;i<=n;i++){
cin>>a[i];
q.push(a[i]);
b.push(a[i]);
}
while(q.size()>1){
int x=q.top();
q.pop();
int y=q.top();
q.pop();
q.push(x*y+1);
}
while(b.size()>1){
int x=b.top();
b.pop();
int y=b.top();
b.pop();
b.push(x*y+1);
}
cout<<b.top()-q.top()<<"\n";
}
return 0;
}
喷水装置(二)
题目描述
有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=100000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入描述
第一行输入一个正整数N表示共有n次测试数据。每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
输出描述
每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。如果不存在一种能够把整个草坪湿润的方案,请输出0。
样例
输入
2
2 8 6
1 1
4 5
2 10 6
4 5
6 5
输出
1
2
cpp
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
using namespace std;
struct qj {
double a,b;
} q[10005];
bool cmp(qj n,qj m) {
return n.a<m.a;
}
int n,t,w,h,r,x,num;
int main() {
cin>>t;
while(t--) {
num=0;
cin>>n>>w>>h;
double H=h/2.0;
for(int i=1; i<=n; i++) {
cin>>x>>r;
if(r>H) {
double t=sqrt(r*r-H*H);
q[++num].a=x-t;
q[num].b=x+t;
}
}
if(num==0) {
cout<<0<<"\n";
continue;
}
sort(q+1,q+num+1,cmp);
int cnt=0,k=0,f=0;
double pr=0;
for(int i=1; i<=num; i++) {
if(pr>=w) {
break;
}
int t=i,ma=q[i].b,ans=i;
while(q[t].a<=pr&&t<=num) {
if(ma<q[t].b) {
ma=q[t].b;
ans=t;
}
t++;
}
if(q[ans].a<=pr) {
cnt++;
i=ans;
pr=q[i].b;
} else {
cout<<0<<"\n";
f=1;
break;
}
}
if(!f) {
cout<<cnt<<"\n";
}
}
return 0;
}
愤怒的家雀子
题目描述
在森林里有一排树。第i棵树的高度是Di。有一只家雀儿,它在第一棵树上,它只有到最后一棵树的顶端才能找到食物
然而,这只鸟力气比较小,无法直接飞到那里。小鸟如果在第i棵树,那么他可以跳到第i+1,i+2,...,i+k棵树,然后必须休息。而且,向上飞要比向下飞难得多。 如果雏鸟跳到一棵不矮于当前树的树,那么他的劳累值会+1,否则不会累积疲劳值(可以滑翔)。 我们如果在飞翔的过程中有目的地选择小鸟降落的树,这样整个飞行过程就不会那么累。
输入描述
第一行1个整数N表示树的个数(2 <= N <= 10^6);
第二行N个整数分别表示第i棵树的高度D[i];
第三行1个整数Q(1 <= Q <= 25)表示K的个数;
接下来Q行,每行1个整数表示K。
输出描述
输出Q行,每行1个整数表示家雀儿在此K情况下最小化的劳累值。
样例
输入
9
4 6 3 6 3 7 2 6 5
2
2
5
输出
2
1
提示
K=2时
家雀儿可以从第一棵树向右飞停在第三、五、七、八、九号树上,它的疲劳值是从第三棵树到第五棵树,从第七树到第八树的飞行过程中积累的,也可以停在第三、五、七、九号树上。
代码
cpp
#include<iostream>
using namespace std;
int n,d[10000005],q,k;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>d[i];
}
cin>>q;
while(q--){
cin>>k;
int pr=1,sum=0;
while(pr+k<n){
int hm=-1,t=pr,ma=-1,t1=pr;
for(int i=pr+1;i<=pr+k;i++){
if(d[i]<d[pr]){
if(hm<d[i]){
hm=d[i];
t=i;
}
}
if(d[i]>=ma){
ma=d[i];
t1=i;
}
}
if(hm==-1){
sum++;
pr=t1;
}
else{
pr=t;
}
}
if(d[pr]<=d[n]){
sum++;
}
cout<<sum<<"\n";
}
return 0;
}