【刷题第八天】贪心——C++
【题目描述】
输入一个高精度的正整数n,去掉其中任意s个数字后剩下的数字按原左右次序组成一个新的正整数。编程对给定的n和s,寻找一种方案使得剩下的数字组成的新数最小。
输出新的正整数。(n不超过240位)
输入数据均不需判错。
【输入】
n
s
【输出】
最后剩下的最小数。
【输入样例】
175438 4
【输出样例】
13
算法分析:
(1)175438中取出7
(2)15438中取出5
(3)1438中取出4
(4)138中取出8
这里很明显就能看出来取出7、5、4的时候前面都是升序,如17是升序后面就降序了,15是升序,14是升序。另外一种情况就是全部是升序,那就只要将后面指定的个数取走就好了。
1 #include <iostream> 2 using namespace std; 3 int main() { 4 char n[240]; 5 char t; 6 int s, len = 0, d = 0, min, k, di, flag = 1, a; 7 cin >> n; 8 cin >> s; 9 while (n[len] != '\0') 10 { 11 len++; 12 } 13 di = len - s; 14 while (s>0) { 15 k = 0; 16 for (a = 0; a < len; a++) 17 { 18 if (n[a] > n[a+1] && a!=len-1) { //这是用来判断什么时候变成降序,另外后面的条件是不让最后一个数和结束符一起比较(主要用来判断这些数是不是全是升序) 19 k = a; 20 break; 21 } 22 } 23 if (k == 0 && a >= len && len > di) { //如果这里全是升序,那就直接删去后面的指定个数即可 24 len = di; 25 break; //这个一定要写 26 } 27 else { 28 for (int j = k + 1; j < len; j++) //删去指定的数。 29 { 30 n[j - 1] = n[j]; 31 } 32 len--; 33 } 34 s--; 35 } 36 flag = 1; 37 for (int i = 0; i < len; i++) 38 { 39 if (n[i] == '0' && i < len - 1 && flag == 1) { //这里就是判断第一个数是不是等于0 40 continue; 41 } 42 else { 43 cout << n[i]; 44 flag = 0; 45 } 46 47 } 48 49 50 return 0; 51 }
【题目描述】
某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,由于该系统还在试用阶段。所以一套系统有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度不大于30000的正整数)。计算要拦截所有导弹最小需要配备多少套这种导弹拦截系统。
【输入】
n颗依次飞来的高度(1≤n≤1000)。
【输出】
要拦截所有导弹最小配备的系统数k。
【输入样例】
389 207 155 300 299 170 158 65
【输出样例】
2
【提示】
输入:导弹高度: 4 3 2
输出:导弹拦截系统k=1
算法分析:这道题目第一感觉有和上一题有类似点,刚开始的时候确实想到直接用升降序的方法,但是是错的。输入样例看着是用升降法是可以做的,但很明显554 345 75 178 51 64 28 18 51 51 542 17
这个用升降法是错的。这个是有三个系统的,我用三条线来表示:
(1)554——345——75——51——28——18——17
(2)178——64——51——51
(3)542
554进入(1),345进入(1),75进入(1),178进入(2),51进入(1){这里很明显就应该进入(1)中,因为和(2)相比离(1)更近,如果选(2)那就不是最优解},64进入(2),28进入(1),18进入(1),51进入(2),51进入(2){不超过即可},542进入(3),17进入(1)
过程就是这样,我想到的是另外取一个数组来放置几条不同的线,根据差的大小放置到各个线中,那么最后这个数组的长度就是系统的个数。
1 #include <iostream> 2 using namespace std; 3 int main() { 4 int n[1000], a = 1, len = 0, m[1000], m_len = 0, min; 5 while (cin >> n[len]) //ctrl+Z之后回车就是输入了 6 { 7 len++; 8 } 9 for (int i = 0; i < len; i++) 10 { 11 min = 30000; //这是用来看和谁的差最小 12 if (m_len == 0) { //如果没有任何一条线就创造一条 13 m[m_len] = n[i]; 14 m_len++; 15 } 16 else { 17 for (int j = 0; j < m_len; j++) //循环各个线,选择相应的线插入 18 { 19 if (m[j] - n[i] >= 0 && m[j] - n[i] < min) { //这个是保证差是正数(如果全是负数就要创造新的线),找到最小的差的线 20 min = m[j] - n[i]; 21 a = j; 22 } 23 } 24 25 if (min == 30000) { //如果没有找到就创造新的线 26 m[m_len] = n[i]; 27 m_len++; 28 } 29 else { //找到了就插入 30 m[a] = n[i]; 31 } 32 } 33 } 34 cout << m_len; 35 return 0; 36 }

浙公网安备 33010602011771号