• 【t098】符文之语


    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    当小FF来到神庙时,神庙已经破败不堪了。但神庙的中央有一个光亮如新的石台。小FF走进石台, 发现石台上有一个数串,而数串
    的上方刻着一串古老的符文之语。精通古符文之语的小FF不费吹灰之力就读懂了文章的意思,其大意是:对于石台上的一串数
    字,你可以在适当的位置加入乘号(设加了k个,当然也可不加,即分成k+1个部分),设这k+1个部分的乘积(如果k=0,则乘
    积即为原数串的值)对m的余数(即mod m)为x;现求x能达到的最小值及该情况下k的最小值,以及x能达到的最大值及该情况下
    的k的最小值(可以存在x的最小值与最大值相同的情况)。小FF还知道,如果他找到了正确的答案,那么就可以通往神庙的下层
    了。但这个问题似乎不太好解决,小FF就找到了你,并答应找到财宝以后和你二八分(当然你拿二……)。
    【数据范围】
    对于30%的数据:2≤字符串的长度L≤50。
    对于100%的数据:2≤字符串的长度L≤1000;2≤m≤50。
    【输入格式】

    第一行为数串,且数串中不存在0; 第二行为m。

    【输出格式】

    四个数,分别为x的最小值和该情况下的k,以及x的最大值和该情况下的k,相邻两个数之间用以个空格隔开。

    Sample Input

    4421
    22

    Sample Output

    0 1 21 0

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t098

    【题解】

    设f[i][j]表示前i个数字组成的数字%m的值为j时最少需要加入的乘号个数;
    设mod[i][j]表示从第i到第j个数字组成的数字%m的值为多少;(这个可以用同余率搞出来);
    令t = (j*mod[i+1][k])%m;
    则f[k][t] = min(f[k][t],f[i][j]+1);
    最后分别顺序枚举、倒序枚举一下i输出相应的f[n][i]就好;
    这里状态的表示感觉不好想。
    想出来后写代码就比较轻松了;

    【完整代码】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int MAXL = 1100;
    const int MAXM = 50+10;
    const int INF = 0x3f3f3f3f;
    
    char s[MAXL];
    int m,a[MAXL],len,mod[MAXL][MAXL];
    int f[MAXL][MAXM];
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        scanf("%s",s+1);
        rei(m);
        len = strlen(s+1);
        rep1(i,1,len)
            a[i] = s[i]-'0';
        rep1(i,1,len)
        {
            mod[i][i] = a[i]%m;
            rep1(j,i+1,len)
                mod[i][j] = ((mod[i][j-1])*10+a[j])%m;
        }
        memset(f,0x3f3f3f3f,sizeof f);
        rep1(i,1,len)
            f[i][mod[1][i]] = 0;
        rep1(i,1,len)
            rep1(j,0,m-1)
                if (f[i][j]<INF)
                {
                    rep1(k,i+1,len)
                    {
                        int t = (j*mod[i+1][k])%m;
                        f[k][t] = min(f[k][t],f[i][j]+1);
                    }
                }
        rep1(j,0,m-1)
            if (f[len][j]<INF)
            {
                printf("%d %d ",j,f[len][j]);
                break;
            }
        rep2(j,m-1,0)
            if (f[len][j]<INF)
            {
                printf("%d %d
    ",j,f[len][j]);
                break;
            }
        return 0;
    }
    
  • 相关阅读:
    DevExpress Winform SearchGridLookUpEdit多选简单设置
    C# yyyyMMdd 类型字符串转换为datetime 类型
    Winform中TextBox文字垂直居中显示
    操作数据库 增删改查
    C# 连接MySql数据库
    XtraEditors三、LookUpEdit、GridLookUpEdit、SearchLookUpEdit
    前端下拉框多选
    php round函数失效
    防御式CSS开发
    微服务解决方案
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626643.html
Copyright © 2020-2023  润新知