2019年月23日

今天继续复习贪心。
经过这几天的磨练,我终于明白,想要用好贪心,就要多做题,做的题目多了,套路就熟悉了。
这样就不至于一看题目,两眼一抹黑,想半天想不出思路来。
所以我们继续搞题。
下面是一道题。
加工木块,每个木块都有自己的质量和长度,如果一个加工的木块的长度和质量都比上一个大,那么不需要调机器,否则花一分钟调机器,机器在一开始启动需要一分钟。
求怎么加工使时间最少。
这个题目的思路是,首先按照质量或者长度排序,接着按顺序对另一个量比较,找出所有能按规矩排列的排列的数量,就是需要的时间。
上代码。

#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct box
{
    int l; //长度
    int w; //质量
    bool u; //是否已被使用
};
int cmp(box x,box y) //排序规则
{
    if(x.w==y.w)
    {
        return x.l<y.l;
    }
    else
    {
        return x.w<y.w;
    }

}
int main()
{
    int m;
    scanf("%d",&m);
    while(m--)
    {
        box a[10000];
        int n,sum=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d %d",&a[i].l,&a[i].w);
            a[i].u=false; 
        }
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++)
        {
            if(a[i].u) //如果被使用过了,那么跳过
            {
                continue;
            }
            int maxx=a[i].l; //存最大值
            for(int j=i+1;j<n;j++)
            {
                if(!a[j].u&&maxx<=a[j].l) //没有被使用,且长度比后面小
                {
                    a[j].u=true;
                    maxx=a[j].l; //最大值更换
                }
            }
            sum++; //时间累加
        }
        cout<<sum<<endl;
        }
        return 0;
}

还有另一道
有m个人每个人有n张牌,牌的大小从1到n*m;知道自己的n张牌的大小。
至少可以赢几次?
这个题的思路是,先把自己的牌从大到小排序,然后挑出对方最大的牌,用自己的牌挨个与之比较。
如果自己的大,自己赢一次,如果自己的小,找到下一个大的牌继续比较。
下面是代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int m,n;,k=1;
    int s[60]; //保存自己的牌的
    int pa[1000];  //全部牌
    while(scanf("%d%d",&m,&n))
    {
        if(m==0&&n==0)
        	return 0;
        int i;
        memset(pa,0,sizeof(pa));
        for(i=0; i<n; i++)
        {
            scanf("%d",&s[i]);
            pa[s[i]]=1; //标记自己的牌
        }
        sort(s,s+n,cmp);
        int a=n*m,sum=0;
        while(pa[a]) //找出除了自己的牌的最大的牌
            a--; 
        for(i=0;i<n;i++)
        {
            if(s[i]>a) //自己的牌大,赢一局
                sum++;
            else
            {
                pa[a]=1; //标记这张牌无人能敌
                while(pa[a]) 找出第二大的牌
                    a--;
           }
        }
        cout<<"Case "<<k<<": "<<sum;
        k++;
    }
    return 0;
}

总之,多做题,多总结,就对了。

猜你喜欢

转载自blog.csdn.net/qq_17679843/article/details/88768536