ZZU2024年迎新赛复盘----J题

 题目如下

 本题出题人给的官方解答代码有点抽象,这里分享一下我的理解

实际上本题我更认为是数学+思维,没有用到任何算法,就是思维要严谨一些,多一些特判

首先保证特殊样例能过,只有一位数,换言之s的size等于0,直接cout<<0

然后就思考,只删一个数字怎么让留下的最小,比如123和321两个例子,我们很容易发现123中我们删除最后一位,也就是递增的字符数组,我们不用特别管,因为在循环输出的时候让循环次数严格小于s.size() ---也就是删掉一个字符的长度,这样就自然截断了最后一位

而321我们发现高位的数字只要一删除,该数字一定是所有删除一个数后最小的一个情况,比如

312--》12,132--》12,1919810--》119810等等,即当s[i]>s[i+1]时,删掉s[i],删除操作可以让该位置的值更新为-1,输出时遇到-1跳过不输出就行了

接下来是特殊数字的判断,这里笔者也是wa了多次,一步步优化找到特殊案例

对于题目告诉你的9011变为11,我们可以发现当某个位置变为-1不输出时,他的下一位可能时0,所以还要引入特例判断-1的下一位是不是零,这里引入position变量记录可能使首位为零的位置,若9001这样连续出现0的情况,我们需要在发现第一个首位0后让position++看首位0的下一个是否还是0,这样10086这种例子也能过了

最后是10000这样的数据,他输出为空,这个特例要特殊处理,好在处理起来也简单,引入flag变量初始为0,如果有输出变为1,如果循环输出完还是没0(没有输出)就专门输出一个0

这样所有情况就考虑妥当了

ac代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
#define int long long
int n;
string s;
void solve(){
   if(s.size()==0)cout<<0;
   for(int i=0;i<s.size();i++){
       if(s[i]>s[i+1]){
           s[i]=-1;
           break;
       }
   }
    int position=0,flag=0;
    for(int i=0;i<s.size();i++){
        if(s[i]==-1){
            position++;
            continue;
        }
        if(s[position]=='0'){
            position++;
            continue;
        }
        cout<<s[i];
        flag=1;
    }
    if(flag==0) cout<<0;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>s;
    solve();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值