今天对问题的感悟:
1,反向思考问题
拿到一个题目我们在做的时候,第一思维是从题目所给问题的正面去考虑问题。如果问题比较简单可以直接做。若没有思路我们可以转换一下思路从相反的角度思考如何求解;可以在纸上写写看那种方案可以实现;
分析一下例题
这个题开始我还想直接对a序列排序。。。太天真了。第一种如果选择删去m位,应该怎么选取区间[1,n-m]每次在区间内选择最大数,可选取出来怎么删除,不会;可以考虑
分析一下第2种: 为什么必须要在[1,m+1]中选取第一位呢? 因为要选最小的,而且选出第一位,下一位的选取要在前一位所在位置的后面。所以【m+1】也要后移一位,m+2;
就这样每次在可选区间选择最小数,(每选一次区间可能变小,最后直接把剩余的数据都选上就完成了。)
2.还有一个技巧,就是对于一串数字。可以用字符型数组存储,因为用整形存储使用时还要对数的每一位进行分解,很麻烦。用字符数组在对数据的输入,取用都挺方便的。
贴一下代码。
3. 对测试数据有点疑惑,选取n-m个,总感觉还有比所得结果更小的数,[1,m+1]中选取1,可在下一个区间中有零,比一还小。。。。但是,扩大区间也不可取!
要是删除m个数的话,不知道怎么删。但是也想不出其他方法,这题要是排序就没意思了。
4.
总结一下,自己对于贪心问题还不太行,差太多了,没好好理解其内涵;可能领悟其内涵还需要点时间,就是有点迷;还要再多回顾一下例题;
还要让 stl 快速上手(这也是我下一步的目标)。
#include<iostream>
using namespace std;
char num[1010];
char ans[1010];
int main()
{
int i,temp,m,t,k;
while(scanf("%s%d",num,&m)!=EOF)
{
t=0; k=0;
int len=strlen(num)-m;
while(len--)
{
temp=t;
for(i=t;i<=m;++i)
{
if(num[temp]>num[i])
temp=i;
}
ans[k++]=num[temp];
m++;
t=temp+1;
}
i=0;
while(ans[i]=='0'&&i<k)//去除前导零
i++;
if(i==k)
printf("0\n");
else
{
for(;i<k;++i)
printf("%c",ans[i]);
printf("\n");
}
}
return 0;
}
/*
4561135489912200122453547
12
1100122453547
*/