贪心算法入门(二)

发布于:2024-12-06 ⋅ 阅读:(43) ⋅ 点赞:(0)
第1题     越野跑 查看测评数据信息

为了能在下一次跑步比赛中有好的发挥,桐桐在一条山路上开始了她的训练 。桐桐希望能在每次训练中跑得尽可能远,不过她也知道农场中的一条规定:独自进山的时间不得超过M秒(1 <= M <= 10,000,000)。

整条山路被桐桐划分成T个长度相同的小段(1 <= T <= 100,000),用S_i表示第i个小段的路况。S_i为U,F,D这3个字母之一,它们分别表示第i个小段是上坡、平地,或是下坡。

桐桐要花U秒(1 <= U <= 100)才能跑完一段上坡路,跑完一段平地的耗时是F秒(1 <= F <= 100),跑完一段下坡路要花D秒(1 <= D <= 100)。注意,沿山路原路返回的时候,原本是上坡路的路段变成了下坡路,原本是下坡路的路段变成了上坡路。

桐桐想知道,在能按时返回农场的前提下,她最多能在这条山路上跑多远。

输入格式

第1行: 5个用空格隔开的整数:M,T,U,F,D。

第2..T+1行: 第i+1行为1个字母S_i,描述了第i段山路的路况。

输出格式

输出1个整数,为桐桐在按时回到农场的前提下,最多能跑到多远。

输入/输出例子1

输入:

13 5 3 2 1

ufudf

输出:

3

样例解释

【样例说明】

说明:桐桐跑步的最大耗时为13秒(这么短...),她跑步的山路一共被划成5段。桐桐跑完一段上坡路的耗时为3秒,平地为2秒,下坡路为1秒。山路各段的走向如下图所示:

                                        

桐桐跑完山路的前3段,然后返回,总耗时为3 + 2 + 3 + 1 + 2 + 1 = 12秒,只比她能在外面呆的时限少1秒。如果她跑得更远,就无法按时回到农场。

#include<bits/stdc++.h>
using namespace std;
int m,t,u,f,d,x,o,i;
string s;
int main(){
    cin>>m>>t>>u>>f>>d>>s;
    for(i=0;;i++){
        if(s[i+1]=='u'||s[i+1]=='d')x=(u+d);
        else x=f*2;
        if(o+x>m||i==s.size())break;
        if(s[i]=='u'||s[i]=='d')o+=(u+d);
        else o+=f*2;
    }    
    cout<<i;
    return 0;
}
第2题     逃生 查看测评数据信息

迷宫被分成N行M列的格子。从上往下看,行的编号是1至N。从左往右看,列的编号是1至M。你现在位于第1行第1列格子,迷宫的出口在第N行第M列的格子。每进入一个格子都要消耗能量。迷宫格子的能量有点奇特,同一行格子消耗的能量是相等的,第1行的每一个格子消耗的能量都是E[1],第2行的每一个格子消耗的能量都是E[2],....第N行的每一个格子消耗的能量都是E[N]。现在你要从左上角格子走到右下角格子,每一步可以从当前格子走到相邻的上、下、左、右四个格子之一,你的目标是消耗最小的总能量。注意:左上角格子和右下角格子消耗的能量也要算。

输入格式

第一行,M和N。(

接下来有N个数,第i个是E[i]。

输出格式

一个整数。

输入/输出例子1

输入:

5  6

3  2  5  4  2  8

输出:

32

样例解释

1<=n<=50,1<=m<=1000000000,1<=e[i]<=1000

#include<bits/stdc++.h>
using namespace std;
long long x,n,s,m,minn=LONG_LONG_MAX;
int main(){
    cin>>m>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        s+=x;
        minn=min(minn,x);
    }
    cout<<s+minn*(m-1);
    return 0;
}
第3题     二零二零 查看测评数据信息

      给出一个字符串S,其中满足S的每一个字符都是数字字符,你要删除S的连续一段字符(也可以删除0个字符),使得剩下的字符依次连接起来的字符串是“2020,可以做到吗?如果可以做到输出“YES”,否则输出“NO”。

输入格式

第一行,一个整数G,表示有G组测试测试。1<=G<=10。

每组测试格式如下:

第一行,一个整数n,表示字符串S的长度。1<=n<=200。

第二行,字符串S。

输出格式

G行,每行一个字符串,“YES”或“NO”,双引号不用输出。

输入/输出例子1

输入:

5

8

20192020

8

22019020

4

2020

5

20002

6

729040

输出:

YES

YES

YES

NO

NO

#include<bits/stdc++.h>
using namespace std;
long long m,n,x;
string s;
int main(){
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>n>>s;
        if(s[0]=='2'&&s[s.size()-3]=='0'&&s[s.size()-2]=='2'&&s[s.size()-1]=='0')cout<<"YES";
	    else if(s[0]=='2'&&s[1]=='0'&&s[s.size()-2]=='2'&&s[s.size()-1]=='0')cout<<"YES";
	    else if(s[0]=='2'&&s[1]=='0'&&s[2]=='2'&&s[s.size()-1]=='0')cout<<"YES";
	    else if(s[s.size()-4]=='2'&&s[s.size()-3]=='0'&&s[s.size()-2]=='2'&&s[s.size()-1]=='0')cout<<"YES";
	    else if(s[0]=='2'&&s[1]=='0'&&s[2]=='2'&&s[3]=='0')cout<<"YES";
	    else cout<<"NO";
	    cout<<'\n';
    }
    return 0;
}
第4题     学生分组 查看测评数据信息

有N组学生,给出初始时每组中的学生个数,再给出每组学生人数的上界R和下界L(L<=R),每次你可以在某组中选出一个学生把他安排到另外一组中,问最少要多少次才可以使N组学生的人数都在[L,R]中。

输入格式

第一行一个整数N,表示学生组数; n<=100
第二行N个整数,表示每组的学生个数;100
第三行两个整数 L,R,表示下界和上界

输出格式

一个数,表示最少的交换次数,如果不能满足题目条件输出-1

输入/输出例子1

输入:

2
10 20
10 15

输出:

5

#include<bits/stdc++.h>
using namespace std;
int n,l,r,a[100005],s,h,s1,s2;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s+=a[i];
    }
    cin>>l>>r;
    if(r*n<s||l*n>s){
        cout<<"-1";
        return 0;
    }
    else{
        for(int i=1;i<=n;i++){
            if(l>a[i])s1+=l-a[i];
            if(r<a[i])s2+=a[i]-r;
        }
    }
    cout<<max(s1,s2);
    return 0;
}
第5题     回文数列 查看测评数据信息

czm非常喜欢回文数列。回文数列是指一个包含N个整数的数列A,分别为A[1],A[2],……,A[n],对于第i(1<=i<=N)个数A[i],都有A[i]=A[N-i+1]。但是回文数字非常难得到。

现在czm想到了一个办法,他可以将数列中,任意两个相邻的数字合并,用它们的和来代替,合并完成的值还可以和其他值不断合并,直到只剩下一个数。要知道一个数肯定是回文数列。

当然,czm希望他的回文数列尽可能长,因此,请你帮助czm计算一下,对于一个长度为N的数列,经过最少多少次合并,可以构成一个回文数列。

输入格式

第一行一个整数N(1<=N<=500000),表示数列中整数的个数。

第二行包含N个正整数,中间用空格分开,表示数列中的数字。

输出格式

输出一个最小合并次数,使得数列变成回文数列。

输入/输出例子1

输入:

3

1 2 3

输出:

1

输入/输出例子2

输入:

5
1 2 4 6 1

输出:

1

输入/输出例子3

输入:

4
1 4 3 2

输出:

2

#include<bits/stdc++.h>
using namespace std;
long long n,a[1000005],s;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
    	cin>>a[i];
    }
    for(int i=1,j=n;i<j;){
        if(a[i]==a[j]){
        	i++;
			j--;
        }
        else if(a[i]>a[j]){
        	a[j-1]+=a[j];
			j--;
			s++;
        }
        else if(a[i]<a[j]){
        	a[i+1]+=a[i];
			i++;
			s++;
        }
    }
    cout<<s;
    return 0;
}
第6题     均分纸牌 查看测评数据信息

有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。
移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
例如 N=4,4 堆纸牌数分别为:  ① 9 ② 8 ③ 17 ④ 6   移动3次可达到目的: 从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。 

输入格式

第一行N。第二行A1 A2 … An (每堆纸牌初始数) 

输出格式

所有堆均达到相等时的最少移动次数。 (1 <= N <= 100,l<= Ai <=10000 ) 

输入/输出例子1

输入:

4

9 8 17 6 

输出:

3

#include<bits/stdc++.h>
using namespace std;
long long a[100005],n,x,t,s;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        t+=a[i];
    }
    x=t/n;
    for(int i=1;i<=n;i++){
    	a[i]-=x;
    }
    for(int i=1;i<n;i++){
        if(a[i]==0)continue;
        a[i+1]+=a[i];
        s++;
    }
    cout<<s;
    return 0;
}
第7题     叠罗汉(NHOI2019xx6)  查看测评数据信息

农场的N头奶牛喜欢玩叠罗汉游戏,就是几头奶牛1头奶牛接着1头奶牛的站成一柱子形状。不过奶牛的力量不一样,用数值Ci表示第i头奶牛它的上面最多可以站多少头奶牛,问这些奶牛最少可以站成几个柱子形状。

输入格式

第一行1个整数N,表示有多少头奶牛。1<=N<=1000。

第二行N个正整数Ci,表示这些奶牛的力量。0<=Ci<=1000。

输出格式

一个整数,表示最少成几个“罗汉”。

输入/输出例子1

输入:

5

0 2 1 2 2

输出:

2

样例解释

样例解释

可以第1、第3、第2头奶牛从上向下叠罗汉;

第4、第5头奶牛叠罗汉。

#include<bits/stdc++.h>
using namespace std;
int n,a[1005],s,k,x;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int t;
		cin>>t;
		a[t]++;
	}
	while(n>k){
		x=0,s++;
		for(int i=0;i<1000;){
			if(i>=x&&a[i]!=0)a[i]--,k++,x++;
            else i++;
		}
	}
	cout<<s;
    return 0;
}
第8题     放书(noip2008mn) 查看测评数据信息

作为一名图书管理员,每天结束时你要把书放回书架。书架和堆放书的地方可以认为在一个X轴上,堆书的地点坐标为0,书架的位置在正、负整数点上。你开始的位置就在0点,你一次最多可以拿N本书,问你最少要走多少路程才可以把书全部放回各自的书架上。

输入格式

第一行有两个整数K和N, 1<=K,N <=50,分别代表书本总数和你一次最多可拿的书本数。后面有K个整数(在-10000到10000之间),分别表示每本书所要放回书架的位置。

输出格式

最少需要的路程。注:你最后可以停在任意的位置,不必返回到开始位置。

输入/输出例子1

输入:

7 2

-37 2 -6 -39 -29 11 -28

输出:

131

输入/输出例子2

输入:

8 3

-18 -9 -4 50  22 -26 40 -45

输出:

158

#include<bits/stdc++.h>
using namespace std;
template<typename T>
T max(T&a,T&b){
    return a<b?b:a;
}
int k,n,s,i,j;
int main(){
    cin>>k>>n;
    vector<int>v(k);
    for(int i=0;i<k;i++){
        cin>>v[i];
    }
    sort(v.begin(),v.end());
    for(i=0;v[i]<=0;i++);
    for(j=0;j<i;j++){
        if(j%n==0)s-=v[j]*2;
    }
    for(int j=v.size();j>i;j--){
        if((v.size()-j)%n==0){
        	s+=v[j-1]*2;
        }
    }
    s-=max(-v.front(),v.back());
    cout<<s;
    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到

热门文章