题解-数字删除

题目描述

小明最近在研究一个数字删除游戏,正要考考佳佳。游戏规则如下:

给定一个正整数,去掉其中若干个数字后剩下的数字按原左右次序将组成一个新的正整数。请问最少删去几个数字,能够使得这个新的正整数合法(不含前导0)且是3的倍数。

小明写下的数字太大,佳佳一时处理不了。请你帮他写一个程序处理出结果吧!

输入

第一行一个整数n,表示小明写下了n正整数。

第2~n+1行每行一个正整数Ai。

输出

共n行,每行一个整数,表示最少删去的数字的个数。如果没有合法的方案,请输出"ERR"(不含引号)。

样例

输入样例

3

1234

1000

2

输出样例

1

3

ERR

提示

【样例解释】

第一组删除1个留下的整数为234或123.

第二组删除3个留下的整数为0。

对于30%的数据,n≤5,Ai≤10910^9109且不含有数字0。

对于60%的数据,n≤5,A¡≤1010000010^{100000}10100000且不含有数字0.

对于100%的数据,n≤5,Ai≤1010000010^{100000}10100000 。(数字的长度可能达到100001位)

分析

可以用动态规划来解决(线性dp)

由于要求不含前导零,所以从后往前转移。

f[i][j]代表 第i位到最后一位组成的数,对3取模等于j时最少需要删的数字的数量

a[i]指 第i位数字模3的结果

则对于第i位数字,有删除和不删除两种情况

若删除,则f[i][j] = f[i + 1][j] + 1

若不删除,则f[i][j] = f[i + 1][(j - a[i] + 3) % 3](注意j - a[i]可能为负数,故需要进行处理)

最终状态转移方程为

f[i][j] = min(f[i + 1][j] + 1,f[i + 1][(j - a[i] + 3) % 3])

对于最终结果,

首先,我们可以枚举i作为最终正整数的起始位置,

如果当前si不为'0'时,则代表可以枚举,即将前 i - 1 个数字全部删去,且保留第i位数字,则局部最优解为

i - 1 + f[i + 1][(0 - a[i] + 3) % 3] (即把状态转移方程的j替换为0),最终结果取最小值即为答案

ps.因为第i位需要保留,所以不能是 i - 1 + f[i][0]

又因为最后一位数字不一定能被3整除,所以只能从1枚举到len - 1,

若最有一位数字能被3整除,那加一个特判 res = min(res,len - 1)即可

代码

c++ 复制代码
#include<bits/stdc++.h>

using namespace std;

const int N = 100000 + 10,INF = 0x3f3f3f3f;

int n;
char s[N];
int a[N];
int f[N][3];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);

    cin >> n;
    while(n--){
        cin >> s + 1;

        int len = strlen(s + 1);

        for(int i = 1;i <= len;i++) a[i] = (s[i] - '0') % 3;

        //初始化
        memset(f,0x3f,sizeof f);
        f[len][a[len]] = 0;
        if(a[len]) f[len][0] = 1;

        for(int i = len - 1;i >= 1;i--)
            for(int j = 0;j <= 2;j++)
                f[i][j] = min(f[i + 1][j] + 1,f[i + 1][(j - a[i] + 3) % 3]);
        
        int res = INF;
        for(int i = 1;i < len;i++)
            if(s[i] != '0') res = min(res,i - 1 + f[i + 1][(0 - a[i] + 3) % 3]);
        if(a[len] == 0) res = min(res,len - 1); // 特判

        if(res == INF) cout << "ERR\n";
        else cout << res << '\n';
    }

    return 0;
}
相关推荐
别动我齐刘海21 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
傻啦嘿哟21 小时前
英雄联盟皮肤爬虫:爬取全皮肤价格与特效,做比价工具
java·c++·爬虫
码匠许师傅1 天前
【C++ 面试真题】24. 聊聊 C++ 的时间日期处理
java·c++·面试
闻道且行之1 天前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
莫浅子1 天前
day01-USB架构与枚举
c++·单片机·嵌入式驱动
不会代码的小猴1 天前
7. JSON
开发语言·c++·笔记·qt·算法·json
沫璃染墨1 天前
《Qt从零入门系列(六):信号与槽进阶——从多种连接方式到Lambda表达式》
开发语言·c++·qt·代码规范·设计规范·qt5
小小龙学IT1 天前
ZeroMQ(libzmq)开源消息库深度解析:brokerless 时代的轻量消息内核
c++·开源
Benny_Tang1 天前
题解:P10230 [COCI 2023/2024 #4] Lepeze
c++·算法
我变成萤火虫1 天前
反悔贪心(经典题目讲解)
c++·算法·贪心算法·stl·排序算法·反悔贪心