好吧,神奇的题目。。
这道题目,神奇的字符单调栈。。
首先预处理出1~n个数(大家都会。)
然后塞进字符串里,输出答案(水~)
然后。。
我们需要将所有的字符存入单调栈中,然后乱搞,就可以输出啦。
不过注意:有的题目可能在单调栈中没有把所有的字符删完,即后面的所有字符都一样,那么此时我们需要直接把后面的多出来的位数减去即可。
还有,单调栈中如果已经减了m位之后就不能再减了
在维护单调队列时我们要尽量让排名靠前的数字被删除(贪心)
这样得到的答案才最优
(这道题我一开始做的时候没有维护单调队列,而是维护上升子序列,导致一部分(80)的点WA,我的锅。。。)
果然还是我太弱了。。
%180 Rank 1的大神zxyer
下面贴代码
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int k,m; unsigned long long num[30050]; unsigned long long qaq[11]; int num1=-1,num2=-1; char ans1[1000005]; char zc[1000005]; char ans[1000005]; int main(){ //freopen("number.in","r",stdin); //freopen("number.out","w",stdout); memset(ans,0,sizeof(ans)); memset(ans1,0,sizeof(ans1)); scanf("%d%d",&k,&m); int tot=1; num[1]=1; int tail1=1,tail2=1; while(k>tot) { if(num[tail1]*2+1>num[tail2]*4+5)num[++tot]=num[tail2]*4+5,tail2++; else num[++tot]=num[tail1]*2+1,tail1++; } int tt=-1; for(int i=1;i<=k;i++) { tt=-1; while(num[i]) { int tmp=num[i]%10; qaq[tmp]++; zc[++tt]=tmp+48; num[i]/=10; } for(int i=tt;i>=0;i--) ans1[++num1]=zc[i]; } printf("%s ",ans1); int cnt=0; int total=m; for(int i=0;i<=num1;i++) { while(m&&cnt&&ans1[i]>ans[cnt])cnt--,m--; ans[++cnt]=ans1[i]; } if(cnt>num1-total+1)cnt=num1-total+1; for(int i=1;i<=cnt;i++) printf("%c",ans[i]); printf(" "); return 0; //fclose(stdin); //fclose(stdout); }