贪心算法2

太难的题没有做出来,所以就写两道印象较为深刻的题。
1.最小新整数
给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。
现在从m位中删除k位(0<k < m),求生成的新整数最小为多少?
例如: n = 9128456, k = 2, 则生成的新整数最小为12456
输入第一行t, 表示有t组数据;
接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出t行,每行一个数字,表示从n中删除k位后得到的最小整数。

#include<bits/stdc++.h>
using namespace std;
char a[1000000000];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int k;
        cin>>a>>k;
        int n=strlen(a);
        while(k--)
        {
            bool f=true;
            for(int i=0;i<n-1;i++)
                if(a[i]>a[i+1])
                {
                    for(int j=i;j<n-1;j++)
                        a[j]=a[j+1];
                    n--;
                    f=false;
                    break;
                }
            if(f)
            {
                char m=a[0];
                int p=0;
                for(int i=0;i<n;i++)
                    if(a[i]>m)
                    {
                       p=i;
                       m=a[i];
                    }
                for(int j=p;j<n-1;j++)
                    a[j]=a[j+1];
                n--;
            }
        }
        for(int i=0;i<n;i++)
            cout<<a[i];
        cout<<endl;
    }
    return 0;
}

第一眼看这题的时候,我没有太在意,因为和一本通上一样,而当时借鉴了别人的题解,没有想的太仔细,只是记住了当时的解法是:从左到右,去掉第一个逆序数,然后就过了,仔细想一想,这个思路缺少了一大部分,没有考虑没有逆序数的情况,所以正确的思路应该是:先从左到右搜索有无逆序数,如有,去掉第一个而不是最大的(如128796,去掉8之后的数比去掉9的小),如果去掉的位数还没有达到目标数,再从左向右搜索(这时应该没有逆序数),每次去掉其中最大的一个。
2.拼点游戏
C和S两位同学一起玩拼点游戏。有一堆白色卡牌和一堆蓝色卡牌,每张卡牌上写了一个整数点数。C随机抽取n张白色卡牌,S随机抽取n张蓝色卡牌,他们进行n回合拼点,每次两人各出一张卡牌,点数大者获得三颗巧克力,小者获得一颗巧克力,如果点数相同,每人各得二颗巧克力,使用过的卡牌不得重复使用。已知C和S取到的卡牌点数,请编程计算S最多和最少能得到多少颗巧克力。
输入包含多组测试数据。
每组测试数据的第一行是一个整数n(1<=n<=1000),接下来一行是n个整数,表示C抽到的白色卡牌的点数,下一行也是n个整数,表示S抽到的蓝色卡牌的点数。
输入的最后以一个0表示结束。
输出对每组数据,输出一行,内容是两个整数用空格格开,分别表示S最多和最少可获得的巧克力数。

int tjsm(int a[],int b[])// b win
{
    int s=0;
    int aleft=1,aright=n;
    int bleft=1,bright=n;
    while(bleft<=bright)
    {
        if(b[bright]>a[aright])
        {
            s+=3;
            bright--;
            aright--;
        }
        else
        {
            if(b[bright]<a[aright])
            {
                s+=1;
                bleft++;
                aright--;
            }
            else//b[bright]==a[aright]
                if(b[bleft]>a[aleft])
                 {
                     s+=3;
                     bleft++;
                     aleft++;
                 }
                 else//b[bright]=a[aright]&&b[bleft]<=a[aleft]
                 {
                     if(b[bleft]==a[aright])//b[bleft]=b[bright]=a[aright]
                     {
                         s+=2;
                         bleft++;
                         aright--;
                     }
                     else//b[bleft]<a[aright]=b[bright]
                     {
                         s+=1;
                         bleft++;
                         aright--;
                     }
                 }
        }
    }
    return s;
}

典型的田忌赛马问题,但我一开始少想了一部,没有比较两个数组最小的数,被卡了好久,具体思路如下
在这里插入图片描述
3
虽然有些题又做了一遍,但仍感觉贪心是目前所学中最难的,主要困难在于想到的策略不是最优的,总会漏掉某些细节,或者有时想到的策略过于繁琐,易导致思路混乱,还是应该多做题来长点见识,没过的题打算以后有时间再试试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值