算法第四章上机实践报告

1.实践题目: 4-2 删数问题

2.问题描述:

给定n位正整数a,去掉其中任意k≤n 个数字后,剩下的数字按原次序排列组成一个新 的正整数。对于给定的n位正整数a和正整数 k,设计一个算法找出剩下数字组成的新数最 小的删数方案。

输入格式:

第 1 行是1 个正整数 a。第 2 行是正整数k。

输出格式:

输出最小数。

输入样例:

在这里给出一组输入。例如:

178543 
4 

输出样例:

在这里给出相应的输出。例如:

13



3.算法描述:

由于测试的数据位数很大,所以用string来纪录输入的整数,再将整数中的每一位数存到数组b[i]中
贪心算法思路:
1.先求出剩余数字的位数d(d=原位数-删除位数),然后从原数据的第d位开始(从个位数开始往左数第c位,且包括这一位),挑出最小的一位c[1](若出现多个相同最小位,则挑最左边的),前面的n位数字全部删除并令k=k-n;
2.若k==0,则结束,输出删剩的数;
  k!=0,则将剩余数字重复第一步的过程直到k==0;

比如例子中的178543为6位数,删去k=4位:

【第一轮】6位数,删去k=4位,剩余2位,

则从第2位(十位数)开始往前,最小的数字是1,取出1,1前面有0位数,则k=k-0,为4,不变,不为0,将剩余的78543重复一轮

【第二轮】仍需删除4位,即为从78543中删除4位,剩余1位,

则从第1位(个位数)往前看,最小的数是3,3前面有4位数,删去,则k=k-4,等于0,删除完毕,结果为13

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int b[100000];
int c[100000];

int main()
{
    int k;
    string a = new char[100000];
    cin >> a >> k;
    char ch;
    int BDigit = a.length(), CDigit;//BDigit为a的位数,CDigit为得到的结果的位数
    for (int i = 0; i < a.length(); i++)//将整数中的每一位数存到数组b[i]中    
    {
        ch = a[a.length() - i - 1];
        b[i] = ch - '0';
    }

    CDigit = BDigit - k;
    int temp = 10;//用来记录每一轮的最小数,一位数的最小数一定<10
    int locate;//记录每一轮取得的数字的位置
    int result = 0;//记录结果
    int judge = 0;//判断
    for (int i = 0; i < CDigit; i++)
    {
        for (int j = BDigit - k - 1; j < BDigit; j++)
        {
            if (b[j] <= temp)
            {
                temp = b[j];
                locate = j;//记录位置
            }
        }
        k = k - (BDigit - locate - 1);//减去一轮中删除的数字个数
        BDigit = locate;
        c[i] = temp;
        if (c[i] != 0)//若前面都是0,则不输出,遇到第一个非零数,改judge为1
        {
            judge = 1;
        }
        if (judge == 1)
        {
            cout << c[i];
        }
        temp = 10;//重置temp
    }
    if (judge == 0)//若剩下的数全部为0,则输出一个0
    {
        cout << 0;
    }

    system("pause");
    return 0;
}

 

4.算法时间及空间复杂度分析:
算法中有两次for循环,需要CDigit*(k+1)次(k在循环中会变化),时间复杂度为O(n^2)
需要一个string及两个int数组记录,空间复杂度为O(n)

5.心得体会:
写第一题时很顺畅,写到第二题时讨论了很久想出上述算法方案(没有上网查,好像网上的方法不一样?),写好后一直答案错误,才发现是k没有做处理,处理好后有没注意到数据位数问题,只通过一个,改string后就AC了。
但是我还是不懂怎么证明贪心选择性质和最优子结构性质......
posted on 2019-11-18 22:10  Aozaki  阅读(164)  评论(0编辑  收藏  举报