萌萌哒的GG
11月15号是GG的破蛋日,这一天萌萌的GG很早就起床,小(zi)小(xi)打扮了一下,就去参加传说中的ACM-ICPC亚洲赛了。 这一去让原本萌萌哒的GG变得更加萌 了,在那凶残的北京赛区中GG被虐的萌萌哒连回家的路都忘记了。于是萌萌的GG便向英勇帅气的DX问起路来,但是DX不想让GG这么容易就能回家,于是他出了一道ACM题,说只要GG能够做出来,就带他回家。 呜呜~~~~(>_<)~~~~ ,这可难倒GG,于是GG哭着向聪明的你请教,希望你能做出来,不然GG就回不了家了。。。 题目是这样紫滴:
数据有T组,给你两个值s,k ( 1 <=T <= 10000,2 <= strlen(s) <= 1000, 0 <= k < strlen(s)); s表示一个字符串(只包含数字,没有前导0),k表示在这个s中删除k个数,使最后得到数(没有前导0)最小。
对于每一组数据输出“Case #x: y”,x表示第几组,y表示删除后得到的最小的数,注意双引号不要输出。
第一组数据删除9和6得到数最小; 第二组删除1,比删除其他数,得到的值小;
广东工业大学ACM集训队新手选拔赛
分析:
1、明天就要蓝桥杯比赛了,今天就猛刷题。读完这道题后,看见输入数字位数会达到1000位,就会想到数组处理,然后会想到不是常规做法,就寻找其中的计算方式。
2、好久没有做过贪心题了,这是一道贪心题。当我们拿到一个数后,输出最小,肯定是从最高开始判断,删除后位数肯定小于等于strlen(s)-k,所以,从最高位开始遍历,寻找相对于下一位大的数字,然后删除。如91623,9比1大,所以删除9,然后遍历,1比6小,不删除,继续遍历,接着6比2大,所以删除6。到此,已经删除2位数字了,结束遍历。用这种方法解决,复杂度是相当低的,10以内就10个数,必删除一个。若是个递增数列,就删除后面数字呗。
3、程序需要处理一下细节,我为了ac它,就没把程序简化了。首先要考虑到当一样大的时候,还要回去删除数字,如9996623,删除2个数字吧,比到9比6时,删除9,然后需要判断前面是否有9。另外就是输出时,注意没有前导0.
LANGUAGE :C++
CODE:
#include <iostream>
#include <cstring>
using namespace std;int main()
{int t,cnt;char arr[1005];cin>>t;int count=0;while(t--){cin>>arr;cin>>cnt;//cout<<arr[0]<<endl;int m=0;int ans=0; //删除相同数字,移位时不再从0开始了 for(int i=0;cnt&&i<strlen(arr)-1;i++){if(arr[i]>arr[i+1]){//cout<<arr[i]<<endl;bool flaggg; do{flaggg=false;for(int j=i;j>ans;j--){arr[j]=arr[j-1];flaggg=true; //判断前面是否有没有删除的数字 }cnt--; m++; //记录删除多少数字后,输出时的起点位置 ans++;//cout<<cnt<<endl;}while(arr[i]>arr[i+1]&&cnt&&flaggg); //判断前面是否有相同的数字 }}bool flag=true;bool fla=true;count++;cout<<"Case #"<<count<<": ";//cout<<m<<endl;for(int i=m;i<strlen(arr)-cnt;i++){if(arr[i]!='0'&&flag) //前导是0时不输出 {cout<<arr[i];flag=false;fla=false;}else if(!flag) //不是前导0或其他数输出 cout<<arr[i];}if(flag&&fla) //如果剩余的全是0时,输出结果0 cout<<0;cout<<endl;}
}
本文发布于:2024-01-29 16:46:26,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170651798816727.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |