A Magic Lamp
求一个数删除m位数字的最小值,且不允许更改数字顺序。
输入
若干行,每行包含一个整数和m;
输出
最小的结果,无前导零
输入样例
178543 4
1000001 1
100001 2
12345 2
54321 2
输出样例
13
1
0
123
321
思路
设这个数为1651708 m为1
一般我们想到的是直接删最大值‘7’,结果为165108
但 是 如 果 删 除 ‘ 6 ’ ,结果为 151708
很明显165108>151708
所以 ,思路如下
1.从最高位开始遍历,删除上升序列的最后一个。如1651708
2.如果最高位无上升序列,则删除最高位数字。如987654321
3.遍历m次,每次删除符合1或2要求的数
相反的删除m个数,就是保留n-m个数
保留的第一个数(下标)一定包含在[1,m+1]中
保留第二个数包含在[+1,m+2]中。
那么解题思路为查找区间[x,y]最小值并记录
原代码如下
#include<bits/stdc++.h>
using namespace std;
int m;
char ch[1200];
pair<char,int> f[1200][11];
void adb(){
int len=strlen(ch);
for(int i=0;i<len;i++)
{
f[i][0]=make_pair(ch[i],i+1);
}
for(int j=1;(1<<j)<=len;j++)
{
for(int i=1;i+(1<<j)-1<=len;i++)
{
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
}
int main(){
while(cin>> ch >> m){
adb();
int l=1,r=m+1,as=strlen(ch)-m;
int oi=0;
while(as--){
int k=log2(r-l+1);
char an1=min(f[l][k], f[r - (1 << k) + 1][k]).first;
int an2=min(f[l][k], f[r - (1 << k) + 1][k]).second;
if(an1!='0'||oi){
cout<< an1;
oi=1;
}
l=an2+1;
r++;
}
if(oi==0){
cout<< 0;
}
cout<< endl;
}
return 0;
}
之后发现样例错误。
第二次调试代码
#include<bits/stdc++.h>
using namespace std;
int m;
char ch[1200];
pair<char,int> f[1200][11];
void adb(){
int len=strlen(ch);
for(int i=0;i<len;i++)
{
f[i][0]=make_pair(ch[i],i+1);
}
for(int j=1;(1<<j)<=len;j++)
{
for(int i=1;i+(1<<j)-1<=len;i++)
{
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
}
int main(){
while(cin>> ch >> m){
adb();
int l=1,r=m+1,as=strlen(ch)-m;
int oi=0;
while(as--){
int k=log2(r-l+1);
cout<< l << " " << r << " "<< k << " " << r-(1<<k)+1;
char an1=min(f[l][k], f[r - (1 << k) + 1][k]).first;
int an2=min(f[l][k], f[r - (1 << k) + 1][k]).second;
cout<< "a";
if(an1!='0'||oi){
cout<< an1;
oi=1;
}
cout<< "b";
l=an2+1;
r++;
}
if(oi==0){
cout<< 0;
}
cout<< endl;
}
return 0;
}
发现K越界了。
AC代码
#include<bits/stdc++.h>
using namespace std;
int m;
char ch[1200];
pair<char,int> f[1200][11];
void adb(){
int len=strlen(ch);
for(int i=1;i<=len;i++)
{
f[i][0]=make_pair(ch[i-1],i);
}
for(int j=1;(1<<j)<=len;j++)
{
for(int i=1;i+(1<<j)-1<=len;i++)
{
f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
}
}
int main(){
while(cin>> ch >> m){
adb();
int l=1,r=m+1,as=strlen(ch)-m;
int oi=0;
while(as--){
int k=log2(r-l+1);
char an1=min(f[l][k], f[r - (1 << k) + 1][k]).first;
int an2=min(f[l][k], f[r - (1 << k) + 1][k]).second;
if(an1!='0'||oi){
cout<< an1;
oi=1;
}
l=an2+1;
r++;
}
if(oi==0){
cout<< 0;
}
cout<< endl;
}
return 0;
}