最近要整算法了,就找个软柿子捏捏吧
删数问题
(抱歉上一个版本误人子弟了)
题目是这样的
题目的洛谷地址
思路分析
我们可以模拟一下自己大脑决策过程
比如下面这个数字
你会优先删谁呢?
那必然是9了
错
删掉9是
5786267135
删掉8是
5782967135
直观点
哪个剩下的小?肯定是删除8更小
继续呢,删谁?
还会删9吗?
删除7更小
继续删6
继续删5
继续……
有没有发现什么规律?
删除的数字总是:从左往右,第一个 后一位小于自己的数字
那么数字从小到大排列怎么办呢?
直接删最后一个即可。剩下的数字肯定是所有删法中最小的
旁枝末节
核心算法就在上面了,还有一些细节问题
N为不超过250位的数字,这肯定不能用传统的int来存储,long long都不行
所以用数组存储吧
那么如何装载输入的字符呢?直接string装载吧,然后再调用toCharArray()函数转成数组arr方便以上的操作
总的循环是删除k个数字,每删一个,k-1,k=0停止删除
while (k!=0)
每次循环中再遍历arr,从左往右找到第一个后一位小于自己的数字,再用一个字符串re记录剩下的数组值,循环结尾把arr赋值为删除后的结果,即re的值(re再次toCharArray()即可)
在循环开头记得把re置空,否则它记录的数据会越来越长
re = "";
for(int i=0;i<arr.length-1;i++){
if(arr[i]>arr[i+1]){
for(int j=i+1;j<arr.length;j++){
re += arr[j];
}//跳过当前这个字符,继续复制接下来的
break;//复制完就相当于已经剔除高位的较大数字,且re存储剩下的字符
}else {
re += arr[i];//在找到较大数前,re复制前面的字符
}
}
if(arr == re.toCharArray()){
re = re.substring(0,re.length()-1);//遍历结果已经相等了,则从最尾端删除数字(已经从小到大排列了)
}
arr = re.toCharArray();
k--;
最后输出re即可(这就是为什么不在循环尾部置空re,最后一次re需要保留值以便输出)
完整代码如下
import java.util.Scanner;
public class Test01 {
public static boolean in_arr(char[] arr,int a){
int p=0;
for(int i=0;i<arr.length;i++){
if(arr[i]==a){
return true;
}
}
return false;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String N = input.nextLine();
String re = null;
char arr[] = N.toCharArray();//存储原来的数字
int k = input.nextInt();//存储要删除的个数
while (k!=0){
re = "";
for(int i=0;i<arr.length-1;i++){
if(arr[i]>arr[i+1]){
for(int j=i+1;j<arr.length;j++){
re += arr[j];
}//跳过当前这个字符,继续复制接下来的
break;//复制完就相当于已经剔除高位的较大数字,且re存储剩下的字符
}else {
re += arr[i];//在找到较大数前,re复制前面的字符
}
}
if(arr == re.toCharArray()){
re = re.substring(0,re.length()-1);//遍历结果已经相等了,则从最尾端删除数字(已经从小到大排列了)
}
arr = re.toCharArray();
k--;
}
System.out.println(re);
}
}