输入为两行内容,第一行是正整数number,1 ≤ length(number) ≤ 50000。第二行是希望去掉的数字数量cnt 1 ≤ cnt < length(number)。
输出保留下来的结果。
325 1
35
3253 1
353
3253 2
53
//AC代码: #include<string> #include<iostream> using namespace std; int main(){ string s; int len,i; while(cin>>s>>len){ i=1; while(len--){ int slen=s.length(); for(i--;i<slen-1;i++) if(s[i]<s[i+1]){ s.erase(s.begin()+i); break; } if(i==slen-1) s.erase(s.end()-1); } cout<<s<<endl; } }//总算过了这道题,至今也没想明白为什么用c版的char *字符串就过不去 //换成c++的string就过去了....... 有毒 有毒
/**
思路:从左到右找第一次出现比后面小的数,找到后s就记录下这个数的位置,然后删除
这个位置数字,例如87784201(s记录第二个7位置),如没找到,s值就是记录最后一个
字符,这时其实是三种情况,全部相等或者从左到右递减,或者中间也可能有相等情况,
反正这时s位置记录的数字是最右边最小的 例如:
987654321(s记录1的位置)
77777777777(s记录最后一个7的位置)
98877777666555(s记录最后一个5的位置)
每次只删除一个数字,然后重头开始直到删除个数等于cnt,用while的优点是每次不用
遍历完整个数列,遍历个数取决于从高位到低位每次满足删除条件的位置,删除一个后
就进入下一次循环
case明显有错,这代码只能跑50%,目前觉得是最优解法
*/
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
StringBuilder yy = new StringBuilder();
yy.append(sc.next());
int cnt = sc.nextInt();
int count = 0;
while (count < cnt) {
int len = yy.length() -1;
int s = 0;
while (s < len && yy.codePointAt(s) >= yy.codePointAt(s+1))
s++;
yy.deleteCharAt(s);
count++; //记录删除个数
}
System.out.println(yy);
}
}
}
绝逼case有问题
大体思路就是每次删除的元素都是从左往右开始第一个出现的小于其右侧相邻元素的元素。
详细思路:
最后通过率为50%
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { char[] str = scanner.next().toCharArray(); int k = scanner.nextInt(); process(str, k); } } private static void process(char[] str, int k) { int i = 1; Stack<Character> stack = new Stack<>(); stack.push(str[0]); while (k > 0 && i < str.length) { while (!stack.isEmpty() && k > 0 && stack.peek() < str[i]) { stack.pop(); --k; } stack.push(str[i]); ++i; } while (k-- > 0) { stack.pop(); } printStack(stack); printCharArr(str, i); System.out.println(); } private static void printStack(Stack<Character> stack) { for (char c : stack) { System.out.print(c); } } private static void printCharArr(char[] str, int start) { while (start < str.length) { System.out.print(str[start++]); } } }
/* 自己的看法,希望大家批评指正 其实我觉得测试用例没有问题 题目明确了输入数组的长度在50000量级 因此选择使用string来表示 我做这道题的思路: 题目说删除给定数字的规定个数使之最大 我们就假设这个数 n 位,要删除 b 个元素,使剩下的 n - b个元素组成最大 另外一个数值的大小取决于它的首位 因为不能改变每个数字的位置,所以其实我们只能在前 b 个元素里选出最大的 作为首位(你只能最多删除 b 个元素,即使 b+1个元素比之前都大 你也没办法把它变成首位) 基于这种思想,b 的大小就是你遍历首位元素(最大元素)的半径 找到前 b 个元素的最大值 max,把 max作为首位,并删除 max之前的元素 这样一来,我们就找到了结果的第一位元素 接下来只要把 b 的值更新(b = b - 之前删掉的元素个数) 也要把这个数更新(删去它最大值后的子序列(不包含最大值)) 这样我们就回到了与上面类似的情况,同样的用此时的半径 b (比刚才小) 去找出最大元作为此时的首位(其实是结果的第二位)再更新 b 值和数字序列 直到最后满足条件退出 下面是我的 AC代码 */ #include<iostream> #include<string.h> #include<vector> using namespace std; string fun(string a,int b) { string res=""; int len = a.length()-b; //删除 b个,其实就是要填满剩下的 n-b个 //我们用上面的方法一个一个填进去 while(len!=0) //len表示要填的长度,填满了退出 { char max = 0; // 找到前 b个中的最大值 for(int i=0;i<=b;i++) { if(max<a[i]) max = a[i]; } int index = a.find_first_of(max); b = b - index; //更新 b 值 res = res + max; //string类型的res存储结果 len--; //填一个格子少一个 // 将首位元素之前的删除,也就是更新原来的数字序列 a = a.substr(index+1); //这是当半径为 0 表示没有再搜索下去的能力了,此时就把后面的元素直接加上 if(b==0) { res = res+a; break; } } return res; } int main() { string a; int b; while(cin >> a >> b) { cout << fun(a,b) << endl; } return 0; }
def getMax(n,k): res = [] while k>0: if len(n)==k: n = [] break maxN = max(n[:k+1]) res.append(maxN) maxin = n.index(maxN) n = n[maxin+1:] k = k-maxin res.extend(n) return res num = input() k = int(input()) n = ' '.join(str(num)).split() n = list(map(int,n)) print(''.join([str(x) for x in getMax(n,k)]))要删除的个数为k,找出前k+1个中最大者,必定不会被删除,然后删除最大者前面的所有数t个,继续对剩下的数中删除k-t个数,以此类推,直到没有要删除的
题目case虽然有bug,自己想通如何去做就行了;
删除t个数之后的最大值,简单理解就是每次删除1个数都要是最大值;
每次删除数,要使他成为最大,肯定是从高位到低位依次进行比较,那么就可以从高位到低位进行遍历找到降序的那个起点数然后删除就行了,遍历的终点为最后一个数
/** JAVA 100%CASE通过 代码 * 思路如下: * 从高位开始,每一位的数肯定最大最好。 * 所以从头查找最大的数。把这个数作为高位,那么这个数就是最大的。 * 比如: * 32918654321 去掉4个数 * step1: * 从9开始递减,查看第一位最大的数可能是多少 * 我们查询到第一次出现9的位子下标为2. * 这个9前面有2个数比9小,那么如果把9作为第一位的话,那么结果肯定是最大的。 * (exception:如果没找到9,则找8,依次递减) * step2: * 所以,继续判断,如果9前面的个数是否小于等于要删除的个数。 * 2<4,说明我们有这么多个数可以删除。 * (exception:如果前面的个数大于要去掉的个数,那么这个数就不能作为高位了,就只能退而求其次选择比这个数小的作为高位) * step3: * 删除9前面的数 得到数 918654321 由于第一位9已经确定了。 * 那么我们的需求就变成: * 18654321 去掉2个数 * step4: * 如果剩下的数的个数正好等于要去掉的个数,那么前面的高位组合就是答案了。 * 如果剩下的数的个数大于要去掉的个数 * 且 如果 要去掉的个数为0,那么结束循环,把前面的所有高位和剩下的数组合就是答案了。 * 反之,要去掉的个数大于0,则把这个再次带入step1进行循环, */ public static void main(String[] args) { Scanner in = new Scanner(System.in); String num = in.nextLine(); int n = Integer.parseInt(in.nextLine()); int count = 0; while(count<n){ for(int i=9;i>=0;i--){ int p = num.indexOf(i+""); if(p!=-1&&p<=n-count){ System.out.print(i); count+=p; num = num.substring(p+1); if(num.length()==n-count){ return; } break; } } } System.out.println(num); }
import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.Scanner; public class Main { // static ArrayList<Character> list = new ArrayList<Character>(); static LinkedList<Character> list = new LinkedList<>(); public static void main(String[] args){ Scanner s = new Scanner(System.in); while(s.hasNext()){ String ss = s.nextLine(); int delNum = Integer.parseInt(s.nextLine()); char[] ch = ss.toCharArray(); for(int i = 0; i<ch.length; i++){ list.add(ch[i]); } //第一种方法 int count = 0; boolean b = true; for(int i=0; i < 10; i++){ while(b){ b = list.remove(Character.valueOf(String.valueOf(i).charAt(0))); if(b==true){ count++; } if(count == delNum){ break; } } if(count == delNum){ break; } b=true; } //========================= // //第二种方法 // Arrays.sort(ch); // for(int i = 0; i<delNum; i++){ // list.remove(Character.valueOf(ch[i])); // } //=============================== StringBuilder sBuilder = new StringBuilder(); for(int i=0; i < list.size(); i++){ sBuilder.append(list.get(i)); } System.out.println(sBuilder.toString()); list.clear(); } } }
int i = 2;cout<<--i<<endl<<i--<<endl; 然后居然输出 0 2 感觉自己电脑中病毒了,望求大神讲解如何将电脑像手机格式化一样的清除数据了 我什么都不要了!!什么都不要了,c,d,e,f,全部清空!!!!!(好吧c盘本来都有数据,就留着吧) 有办法么???? #include<iostream> #include<algorithm> #include<string> #include<cstring> #include<cmath> #define N 100001 #define M 1001 using namespace std; int main(){ string s; int len,i; while(cin>>s>>len){ i=1; while(len--){ int slen=s.length(); for(i--;i<slen-1;i++) if(s[i]<s[i+1]){ s.erase(s.begin()+i); break; } if(i==slen-1) s.erase(s.end()-1); } cout<<s<<endl; } } /*int main() { int n; string a; while(cin>>a>>n) { int i = 1; while(n--) { for(--i;i<a.length()-1;i++) { if(a[i+1]>a[i]) { a.erase(i,1); break; } if(i==a.length()-2) a.erase(a.length()-1); } } cout<<a<<endl; } return 0; }*/ /*int main() { int n;string a; while(cin>>a>>n) { int i = 1;cout<<a.end(); while(n--) { int temp = 0; for(--i;i<a.size()-1;i++) { if(a[i]<a[i+1]) { a.erase(i);temp = 1; break; } } if(temp==0) {a.erase(a.end()-1);} } cout<<a<<endl; } }*/ /*int main(){ string a; while(cin>>a) { int n; cin>>n; for(int k = 0;k<n;k++) { int i = a.find("0"); if(i==a.npos) i = a.find("1"); if(i==a.npos) i = a.find("2"); if(i==a.npos) i = a.find("3"); if(i == a.npos) i = a.find("4"); if(i ==a.npos) i = a.find("5"); if(i == a.npos) i = a.find("6"); if(i == a.npos) i = a.find("7"); if(i == a.npos) i = a.find("8"); if(i == a.npos) i = a.find("9"); if(i==a.npos) a.erase(a.end()-1); a.erase(i,1); } cout<<a<<endl; } return 0; }*/ /*int i = a.find("q"); if(i!=a.npos) cout<<i<<endl; a.erase(i,1); cout<<a<<endl;*/
通过30%的case。。。一度怀疑case有毒。 思路是找到0-cnt范围内的最大一个数,再删除最大数之前的所有数,cnt-n, 即把最大的值提到最前一个位置,再将 余下的数列重复同样的操作,直到cnt=0 private static String getMaxAfterCut(StringBuffer sb, int cnt) { // TODO Auto-generated method stub StringBuffer sBuffer = sb; if(sBuffer.length()>1000 || cnt>sBuffer.length() || cnt <1 || sBuffer.length()<1) return ""; int max = Integer.MIN_VALUE; int maxpos_start = -1; int maxpos_end = maxpos_start; while(cnt>0) { max = Integer.MIN_VALUE; int start = maxpos_end+1; if(start+cnt >= sBuffer.length()) break; for(int i = start;i<start+cnt+1;i++) { if(sBuffer.charAt(i) > '9' || sBuffer.charAt(i)<'0') return ""; if(sBuffer.charAt(i) > max) { maxpos_end = maxpos_start = i; max = sBuffer.charAt(i); }else if(sBuffer.charAt(i) == max) { maxpos_end++; } } sBuffer.delete(start, maxpos_start); cnt -= (maxpos_start-start); maxpos_end -= (maxpos_start-start); } for(;cnt>0;cnt--) { //如果检测到数列结尾cnt不为0,那么再对结尾处的几个数进行删除。 if(maxpos_end+1 >= sBuffer.length()) { sBuffer.deleteCharAt(maxpos_end--); continue; } if(sBuffer.charAt(maxpos_end) < sBuffer.charAt(maxpos_end+1)) { sBuffer.delete(maxpos_end-cnt+1, maxpos_end+1); break; }else { sBuffer.deleteCharAt(maxpos_end+1); } } return sBuffer.toString(); }
#include <bits/stdc++.h> using namespace std; int main(){ string s; int cnt, l, i=0; cin>>s>>cnt; l = s.length(); while(i<l-1 && cnt>0){ if(s[i] >= s[i+1]) i++; else{ s = s.substr(0, i) + s.substr(i+1); l--; cnt--; i = max(i-1, 0); } } if(cnt) s = s.substr(0, l-cnt); cout<<s<<endl; return 0; }
#include <iostream> #include <algorithm> #include <string> #include <stack> using namespace std; string n; int k; int main(){ cin >> n >> k; stack<char> cur, nums; int len = n.length(); for(int i = len - 1; i >= 0; i --) nums.push(n[i]); while(!nums.empty() && cur.size() + nums.size() > len - k){ if(!cur.empty() && nums.top() > cur.top()) cur.pop(); else{ cur.push(nums.top()); nums.pop(); } } while(!nums.empty()){ cur.push(nums.top()); nums.pop(); } while(cur.size() > len - k) cur.pop(); string rnt; while(!cur.empty()){ rnt += cur.top(); cur.pop(); } reverse(rnt.begin(), rnt.end()); cout<<rnt<<endl; return 0; }
import java.util.Scanner; /* * 123 ,1 升序,就去掉123->23 。 * 321 ,1 没有升序,从后面去掉321->32. */ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { StringBuilder sb = new StringBuilder(); sb.append(sc.next()); int len = sb.toString().length(); int cnt = sc.nextInt(); //异常处理 if (cnt >= len) { System.out.println("0"); } //正常逻辑部分 int j = 1; //j用来存储之前遍历过的位置 boolean find = true; //标识这次遍历是否找到过升序的位置 while (cnt > 0 && find) { find = false; for (int i = j; i < sb.length(); i++) { int numa = sb.charAt(i - 1) - '0'; int numb = sb.charAt(i) - '0'; if (numa < numb) { find = true; sb.deleteCharAt(i - 1); cnt--; if (i - 1 > 0) { j = i - 1; //记录上次遍历的位置 } else { j = 1; } break; } } } String res = sb.toString(); if (cnt > 0) {//如果升序对不满足需要,就从后面减去cnt个数 res = (String) sb.subSequence(0, sb.length() - cnt); } System.out.println(res); } } }
s,n=list(input()),int(input()) assert n>=0 and n<= len(s) c,i,m=0,0,len(s)-n while i<len(s)-1 and c < n: if s[i] < s[i+1]: s.pop(i) c+=1 i = i-1 if i else 0 else: i+= 1 print(''.join(s[:m]))
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
string str;
int count;
while(cin >> str >> count) {
for(int i = 0;i < count;i++) {
int haserased = 0;
for(int j = 0;j < str.size()-1;j++) {
if(str[j] < str[j+1]) {
str.erase(str.begin()+j);
haserased = 1;
break;
}
}
if(haserased == 0) {
str.erase(min_element(str.begin(), str.end()));
}
}
cout << str << endl;
}
return 0;
}