2 条题解

  • 1
    @ 2023-5-26 23:32:07

    *想要字典序最小,要让较小的往前靠,所以遍历到一个字符时看一下这个字符后面的字符有没有比他小的

    1. 有比当前字符小的,让后面的前移,让当前的字符变成min(d+1,9),插到合适的位置
    2. 没有比当前小的,就要把这个字符存储起来输出
    3. 貌似这种遍历方法需要借助双层循环,但是|s|<1e5,会超时,需要借助一个cnt数组,先把所有的字符转成数字存起来,再次循环这个串时只需要减去当前的字符,在从0循环到9,看有没有比当前小的,在按1,2过程处理
    4. 输出时,同样从0循环到9,如若这个数不是0,输出总数量的该数,,这样可以保证按升序输出,时间复杂度O(10*x.szie()),可顺利AC本题!
    • 代码如下
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int cnt[20];
    int ans[20];
    const int N=2e5+10;
    void solve() {
    	memset(cnt,0,sizeof(cnt));
    	memset(ans,0,sizeof(ans));
    	string x;
    	cin>>x;
    	for(int i=0; i<x.size(); i++) {
    		int p=x[i]-'0';
    		cnt[p]++;
    	}
    	int flag=0;
    	for(int i=0; i<x.size(); i++) {
    		int o=x[i]-'0';
    		cnt[o]--;
    		for(int j=0; j<=9; j++) {
    			if(cnt[j]&&j<x[i]-'0') {
    				flag=1;
    				int p=x[i]-'0';
    				if(p==9)
    				ans[9]++;
    				else
    				ans[(p)+1]++;
    				break;
    			}
    		}
    		if(!flag)
    		ans[o]++;
    		flag=0;
    	}
    	for(int i=0;i<=9;i++)
    	{
    		if(ans[i])
    		{
    			for(int j=1;j<=ans[i];j++)
    			{
    				cout<<i;
    			}
    		}
    	}
    	cout<<endl;
    }
    int main() {
    	std::ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    	int t;
    	cin>>t;
    	while(t--) {
    	  solve();
    	}
    }
    

    信息

    ID
    811
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    162
    已通过
    30
    上传者