社区讨论
复杂度为O(k)~O(n+k)的算法
P1106删数问题参与者 5已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mi6gg1mq
- 此快照首次捕获于
- 2025/11/20 04:28 4 个月前
- 此快照最后确认于
- 2025/11/20 04:28 4 个月前
思路:如果前数大于后数,则删除前数。
实现:字符数组的前部为升序序列,后部分为未处理序列。
前部最后数与后部首数比较,如果前数小于等于后数,后数移到前数后面。
如果前数大于后数,则删除前数,后数不动。
前后部分都剔除前导0后,依次输出即可。
设n为数字位数,k为删除位数。时间复杂度最好为O(k),最差O(n+k);
代码实现如下:
···c
CPP#include<stdio.h>
char s[10000002];
int k;
int main(){
scanf("%s%d",s,&k);
int i=0,j=1; //i-前数下标,j-后数下标
while(k>0){
if(i<0) s[++i]=s[j++]; //如果前部空,后数移一个到前部
while(s[i]<=s[j]) s[++i]=s[j++]; //前数小于等于后数,后数移到前部。
i--,k--; //前数大于后数,删除前数。
} //结束时,i指向前部最后一个数,j指向后部第一个数
s[i+1]=0; //前部变成字符串
for(i=0;s[i]=='0';i++); //前部串删除前导0
if(s[i]==0) for(;s[j]=='0';j++); //后部串删除前导0
printf("%s%s\n", s+i,s+j); //输出前部串和后部串
return 0;
}
CPP回复
共 4 条回复,欢迎继续交流。
正在加载回复...