算法第四章上机实践报告

发布时间:2022-06-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了算法第四章上机实践报告脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

1.题目:删数问题

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

输入格式:第 1 行是1 个正整数 a。第 2 行是正整数k。

输出格式:输出最小数。

    输入样例:                输出样例:

 

算法第四章上机实践报告

      

算法第四章上机实践报告

 

2.贪心选择性质

2.1 思路

题目要求的是删除k个数字之后的最小数,假设输入序列的个数为n,本题可以转化为:在输入序列中取n-k个数构成最小数。我们每次取的构成最小数的数值就是当前序列的最小值,由于取出的数要按原次序排列,所以本题要考虑以下两种情况:

①选择当前序列的最小值后,最小值后面序列的个数小于我们还需要的数。这种情况我们就要舍弃掉第一小的数,选择第二小的数判断是否符合条件,若不符合继续去第三小的数,以此类推,直到找到符合条件的数,break退出。

②选择当前序列的最小值后,最小值后面序列的个数大于或等于我们还需要的数。这种情况当然就是我们需要的啦。

考虑以上两种情况之后,还要注意,第一位数值若为0,不能输出。

2.2 代码

#include <iostream>

#include <string.h>

#include <algorIThm>

using namespace std;

char a[1000];

struct Num{

int arr;//数值

int brr;//下标

};//弄个结构体是为了快速排序的时候可以返回下标

Num num[1000];

Num num2[1000];//因为快速排序之后num会变成快排之后的序列,用num2保留原本序列

int k;

bool cmp(Num x,Num y){

if(x.arr==y.arr){

return x.brr<y.brr;

}

return x.arr<y.arr;

}

//快速排序

int vv(Num aa[],int start,int end,int min){

sort(aa+start,aa+end,cmp);

return aa[min].brr;

} //弄个min是为了能够找到第二小、第三小...的数

int main() {

cin>>a;

cin>>k;

int n=strlen(a);//求出a的长度

bool cc=false;//一开始还没输出,初始值设为false

for(int i=0;i<n;i++){

num[i].arr=a[i]-48;

num[i].brr=i;

}//a是个字符数组,这里把它转成整型数组

for(int i=0;i<n;i++){

num2[i].arr = num[i].arr;

num2[i].brr = num[i].brr;

}//复制

int w=n-k;//需要找几次

for(int i=0;i<w;i++){

int min = 0;

int result = vv(num,0,n,min);

//如果找到的数符合要求

if(n-1-result >= w-i-1){

//为0,但不是第一个

if(num2[result].arr==0&&cc==true){

cout << num2[result].arr;

}else{  //不为0

if((num2[result].arr)!=0){

cout << num2[result].arr;

cc=true;//记得设为已经有输出了

}

}

n=n-result-1;//取得符合条件得数后,序列就变成该数后面的序列了

for(int ii=0;ii<n;ii++){

num[ii].arr = num2[ii+result+1].arr;

num[ii].brr = ii;

num2[ii].arr = num[ii].arr;

num2[ii].brr = num[ii].brr;

}

}else{//不符合要求,循环找到符合要求的,类似上面

for(min=1;min<n;min++){

int resultt = vv(num,0,n,min);

if(n-1-resultt >= w-i-1){

if(num2[resultt].arr==0&&cc==true){

cout<<num2[resultt].arr;

}else{

if((num2[resultt].arr)!=0){

cout<<num2[resultt].arr;

cc=true;

}

}

n=n-resultt-1;

for(int iii=0;iii<n;iii++){

num[iii].arr = num2[iii+resultt+1].arr;

num[iii].brr = iii;

num2[iii].arr = num[iii].arr;

num2[iii].brr = num[iii].brr;

}

break;

}

}

}

}

return 0;

}

3.@R_24_1304@分析

时间复杂度应该是O(n*(n-k))

理由:本题要找n-k次,找到合适的数值后都要遍历复制数组,平均时间复杂度为n/2,综合起来时间复杂度为:O(n*(n-k))——取决于k的大小,若k很小的话,约等于O(n^2)

4.对贪心算法的理解

在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的“局部最优解”。

因此贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。

5.疑难杂症

还有一种输入方法,为什么已经用long long int,足够长了还不让我过PINTIA,所有输入样例都过了,就是PINTIA不让我过。

不过用long long int的方式定义a,输入后再转成数组会导致倒序,代码写起来有点复杂。以下就是long long int的方式定义a的代码:

#include <iostream>

#include <algorithm>

using namespace std;

long long int a;

long long int k;

struct Num{

int arr;//数值

int brr;//下标

};

Num num [1000];

Num num2 [1000];

bool cmp(Num x,Num y){

if(x.arr==y.arr){

return x.brr<y.brr;

}

return x.arr<y.arr;

}

//快速排序

int vv(Num aa[],int start,int end,int min){

sort(aa+start,aa+end,cmp);

return aa[min].brr;

}

int main() {

cin>>a;

cin>>k;

int n=0;

bool cc=false;

while(a!=0){

num[n].arr=a%10;

a=a/10;

n=n+1;

}//求得共有n个数

for(int i=n-1;i>=0;i--){

num[i].brr=n-1-i;

}

for(int i=0;i<n;i++){

num2[i].arr = num[i].arr;

num2[i].brr = num[i].brr;

}

//总共要找几次

int w=n-k;

for(int i=0;i<w;i++){

int min=0;

int result = vv(num,0,n,min);

//如果找到的数符合要求

if(n-1-result >= w-i-1){

//为0,但不是第一个

if((num2[n-1-result].arr)==0&&cc==true){

cout << num2[n-1-result].arr;

}else{  

if((num2[n-1-result].arr)!=0){

cout << num2[n-1-result].arr;

cc=true;

}

}

for(int i=0;i<n-1-result;i++){

num[i].arr = num2[i].arr;

num[i].brr = n-result-2-i;

}

n=n-result-1;

}else{//不符合要求

for(min=1;min<n;min++){

int resultt = vv(num,0,n,min);

if(n-1-resultt >= w-i-1){

if((num2[n-1-resultt].arr)==0&&cc==true){

cout<<num2[n-1-resultt].arr;

}else{

if((num2[n-1-resultt].arr)!=0){

cout<<num2[n-1-resultt].arr;

cc=true;

}

}

for(int i=0;i<n-1-resultt;i++){

num[i].arr = num2[i].arr;

num[i].brr = n-resultt-2-i;

}

n=n-resultt-1;

break;

}

}

}

}

return 0;

}

脚本宝典总结

以上是脚本宝典为你收集整理的算法第四章上机实践报告全部内容,希望文章能够帮你解决算法第四章上机实践报告所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。