H. 数字游戏
给你一个N位数,从中去掉K个数字,能得到的最大的数是多少?
INPUT
有T测试数据,每组测试数据第一行由N和K2个整数组成(1 ≤ K < N ≤ 500 000),第二行是N位数(非0开头)。
OUTPUT
对每组数据输出去掉K个数字得到的最大数。
SAMPLE TESTS
IN |
OUT |
3 4 2 1924 7 3 1231234 10 4 4177252841 |
94 3234 775841
|
删数问题解释:
采用的是利用队列的方式来进行的操作 ,每次进行10次即可找到最大值,总共寻找n-k个最大值就可以了,
例如
7 3
1 2 3 1 2 3 4
位置为 0 1 2 3 4 5 6
从0- 3 的位置上找到最大值
9个队列 0 1 2 3 4 5 6 7 8 9
位置 0 1 2
从9-0遍历 遇到队列非空切 left >遍历的位置时即可 选择 3;
left=2 即 选择3时的位置
然后记录下一个位置
9个队列 0 1 2 3 4 5 6 7 8 9
位置 0 1
3
让后从9-0遍历 到2时 将位置1踢走 然后 到1时 将位置0踢走,然后到3得出正确结果。
另一种算法:
将 所有的位置 都放到0-9 这个位置中 用一个区间来卡住,从9-0开始遍历,在区间左边的值pop,不管区间右边的值,如果遇到刚好在区间里面的值就是你要找到的值,以此值所在的位置当做左区间,右区间加1即可。
#include<stdio.h> #include<iostream> #include<string.h> #include<queue> using namespace std; queue<int> my[11]; char a[501000]; char b[501000]; int main() { int i,k,n,x,ji,left,max,j,flag,num; scanf("%d",&x); while(x--) { memset(b,'0',sizeof(b)); for(i=0;i<=9;i++) { while(my[i].empty()==0) //将队列里全部的值pop { my[i].pop(); } } ji=0; scanf("%d %d",&n,&k); scanf("%s",a); for(i=0;i<=k;i++) //输入【】里面是值的大小 push的是值的位置 { my[ a[i]-'0' ].push(i); } for(j=9;j>=0;j--) { if( my[j].empty()==0 ){ //如果不为空 将之赋给只包括正确答案的b数组内。 b[ji]=('0'+j); ji++; left=my[j].front(); my[j].pop(); break;} } max=k+1; for(i=1;i<=n-k-1;i++) { my[ a[max]-'0'].push(max); max++; flag=0; for(j=9;j>=0;j--) { while(my[j].empty()==0) { if(left>my[j].front() ){my[j].pop();continue;} //要注意这里的continue,因为没加 wa了好多次。 if(left<my[j].front() ){ flag=1; b[ji]='0'+j; ji++; left=my[j].front(); my[j].pop(); break;} } if(flag==1)break; } } b[ji]='\0'; printf("%s\n",b); 输出正确答案。 } }