zoukankan      html  css  js  c++  java
  • 贪心上机训练题解

    终于我把贪心的上机训练做完了,现在就把这六道题说一下

    第一题 数列极差

    贪心策略:

    从小到大排序,每次擦掉最大的两个数,然后剩下的就是最小的
    从小到大排序,每次擦掉最小的两个数,然后剩下的就是最大的
    稍微提示一下,我们每次都要擦掉最小的两个数,所以每一遍都要拍一遍序
    并且:千万别排成别的数组
    知道了这样的贪心策略,程序也很好写出来

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n,a[50050],b[50050],c[50050];
    int minn,maxx;
        void ask_min(){
            for(int i=1;i<n;i++){
        		b[i+1]=b[i]*b[i+1]+1;
        		sort(b+1,b+n+1);
            }
            minn=b[n];
        }
        void ask_max(){
            for(int i=n;i>1;i--){
            	
                c[i-1]=c[i]*c[i-1]+1;
                sort(c+1,c+i);
            }
            maxx=c[1];
        }
        int main(){
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                b[i]=a[i];
                c[i]=a[i];
            }
            sort(c+1,c+n+1);
            sort(b+1,b+n+1);
            ask_min();
            ask_max();
            printf("%d",minn-maxx);
            return 0;
        }
    

    第二题 数列分段

    贪心策略:

    每段尽可能接近m
    code:

    #include<bits/stdc++.h>
    using namespace std;
    int m,n,sum,ans;
    int a[100010];
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int i=1;i<=n;i++){
    		sum+=a[i];
    		if(sum==m){
    			ans+=1;
    			sum=0;
    			continue;
    		}
    		if(sum>m){
    			ans+=1;
    			i--;
    			sum=0;
    			continue;
    		}
    		if(sum<m&&i==n){
    			ans+=1;break;
    		}
    	}
    	printf("%d",ans);
    	return 0;
    }
    

    第三题 线段

    例题一...
    code:

    #include<bits/stdc++.h>
    using namespace std;
    int n,record,ans;
    struct Node{
    	int b,e,w;
    }a[1000010];
    bool cmp(Node x,Node y){
    	if(x.e==y.e) return x.w<y.w;
    	return x.e<y.e;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d%d",&a[i].b,&a[i].e);
    		a[i].w=a[i].e-a[i].b;
    	}
    	sort(a+1,a+n+1,cmp); 
    	for(int i=1;i<=n;i++){
    		if(record<=a[i].b){
    			record=a[i].e;
    			ans++;
    		}
    	}
    	cout<<ans;
    	return 0;
    } 
    

    第四题 家庭作业

    例题五...

    但是

    我把代码复制过去竟然没过,于是稍微优化了一下
    最开始,我打了个快读,反而更慢了(难道说字符串还没有scanf优秀?)
    所以就开始从贪心实现这方面思考,怎么才能优化
    搜索有剪枝,剪掉多余的,无用的循环、搜索
    我就让贪心也剪掉多余的循环
    用一个dis来储存现在究竟到了哪一天(前面的天数都不能再做作业了)
    这样当后面的再有x[i].a < dis 的就continue了
    减少了进入下一个循环的次数
    于是就成功的过了这道题
    code:

    #include<bits/stdc++.h>
    using namespace std;
    int n,ans,dis;
    struct Node{
        int a,b;
    }x[1000005];
    bool cmp(Node xx,Node yy){
    	if(xx.b==yy.b) return xx.a<yy.a;
        return xx.b>yy.b;
    }
    #define rg register
    inline int read(){
    	rg int s=0,f=0;
    	rg char ch=getchar();
    	while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
    	while(isdigit(ch)) s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
    	return f?-s:s;
    }
    bool fk[1000005];
    int main(){
    //    scanf("%d",&n);
    	n=read();
        for(rg int i=1;i<=n;i=-~i){
        	x[i].a=read();
        	x[i].b=read();
        }
    	sort(x+1,x+n+1,cmp);
        for(rg int i=1;i<=n;i=-~i){
        	if(x[i].a<dis) continue;
        	int bj=1;
            for(rg int j=x[i].a;j;--j){
                if(!fk[j]){
                    fk[j]=1;
                    bj=0;
                    ans+=x[i].b;
                    break;
                }
            }
    		if(bj==1) dis=x[i].a;
        }
        printf("%d",ans);    
        return 0;
    }
    

    第五题 钓鱼

    这道题一开始我是真心不会,问的本机房的一位神犇,他说这是一道DP
    但是DP我还没学,而且书上给的上机训练的的确确说这道题是贪心。
    转过头去,问另一位大佬,他用了几分钟时间就想出了贪心思路
    直接交,立马AC
    所以,贪心还是需要多做题,这样才能立刻想出来。

    贪心思路:

    我们可以把每次要去的最远的鱼塘模拟一遍,之后就知道了到每个鱼塘所需的走路时间
    如此之后,它的走路消耗便可以不算了
    题目就变成了:有n个鱼塘,到每个的距离都是0
    怎样在每个鱼塘钓鱼...
    这样它的贪心策略也就变成了:每次看哪一个鱼塘里的与最多。
    code:

    #include<bits/stdc++.h>
    using namespace std;
    int n,h,t[105],ans,c[105],sum;
    struct Node{
    	int a,m;
    }x[105];
    struct Nod{
    	int a,m;
    }y[105];
    bool cmp(Nod x,Nod y){
    	return x.a>y.a;
    }
    int main(){
    	scanf("%d%d",&n,&h);
    	h*=12;
    	for(int i=1;i<=n;i++) scanf("%d",&x[i].a);
    	for(int i=1;i<=n;i++) scanf("%d",&x[i].m);
    	for(int i=2;i<=n;i++) scanf("%d",&t[i]);
    	t[1]=0;
    	for(int i=1;i<=n;i++){
    		h-=t[i];
    		ans=0;
    		for(int j=1;j<=i;j++){ 
    			y[j].a=x[j].a;
    			y[j].m=x[j].m;
    		}
    		for(int j=1;j<=h;j++){
    			sort(y+1,y+i+1,cmp);
    			if(y[1].a<0) continue;
    			ans+=y[1].a;
    			y[1].a-=y[1].m;
    		}
    		if(ans>sum) sum=ans;
    //		cout<<ans<<"
    ";
    	}
    //	for(int j=1;j<=n;j++){
    //			cout<<y[j].a<<" ";
    //	}
    	printf("%d",sum);
    	return 0;
    } 
    

    第六题 糖果传递

    看这题第一眼:这不均分纸牌吗?
    再多看几眼,这题咋整?

    数学:

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    long long sum,n,need,ans;
    long long y[1000005],a[1000050],x[1000050];
    int main(){
        scanf("%lld",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            sum+=a[i];
        }
        need=sum/n;
        sum=a[1];
        for(int i=2;i<=n;i++){
            y[i]=-((i-1)*need-sum);
            sum+=a[i];
        }
        sort(y+1,y+n+1);
        memset(a,0,sizeof(a));
        x[1]=y[(n+1)/2];
    //    cout<<x[1]<<"   sdf;laj
    ";
        for(int i=1;i<=n;i++){
    //    	cout<<x[i]<<" ";
            a[i]=x[1]-y[i];
    //        cout<<a[i]<<" ";
        }
    //    for(int i=1;i<=n;i++) cout<<x[i]<<" ";
        for(int i=1;i<=n;i++) ans+=abs(a[i]);
        printf("%lld",ans);
        return 0;    
    }
    

    只有六道练习题,所以还没完全掌握,之后一定要多刷题!

  • 相关阅读:
    Android源码之Gallery专题研究(2)
    Android源码之Gallery专题研究(1)
    Android UI 优化——使用HierarchyViewer工具
    如何打开USB OTG功能:
    JavaSE入门学习5:Java基础语法之keyword,标识符,凝视,常量和变量
    Multiply Strings
    android动态控制组件的位置、大小和新的动画
    linux系统编程:线程同步-信号量(semaphore)
    imx6q GPIO功能的用法
    NoSQL数据库概览及其与SQL语法的比較
  • 原文地址:https://www.cnblogs.com/fashpoint/p/11318971.html
Copyright © 2011-2022 走看看