2023-2-8训练题

问题 D: 句子

题目描述

明明与可可经常在网上聊天,但最近他们发现父母们可能查看了他们的隐私谈话。因此他们发明了一些加密方法的语言。
所有合法的单词在给定的单词列表中。一个句子由一些合法单词连续组成(没有空格)。每个单词可以出现任意多次。特殊的加密方法是:每个单词在传送之后,它的字母有可能打乱了重新排列。这次加密的代价定义为:加密前的单词和加密后的单词有多少位置上的字母不相同。比如:“abc” 变为 “abc”,则代价为0。如果变为"acb"、“cba"或"bac"则代价为2。如果变为"bca” 或 "cab"则代价为3。
对于接收到的句子,解码成加密前的句子可能有多种方案,但明明和可可知道只有句子的加密总代价最小的方案才是真正的原来的句子。面对这么复杂的加密语言,他们的父母当然看不懂。但不幸的是,他们自己也搞不懂了。他们需要你帮助研究。
任务:
对于给定的合法单词列表和加密后的句子,求出由合法单词通过加密形成现在句子的最小代价。如果没有可能,则输出-1。
提示:一个单词如果出现多次,每次加密后的单词并不一定相同。

输入

第一行:一个整数 n,表示合法单词个数。
下面 n 行:每行一个字符串,表示一个合法单词。
最后一行:一个字符串,表示加密后的句子。

输出

只一行,一个整数。
样例输入
4
one
two
three
there
neotowheret
样例输出
8

提示

样例解释:
“one” -> “neo” 代价为 3
“two” -> “tow” 代价为 2
“three” -> “heret” 代价为 3
“there” -> “heret” 代价为 5
最小代价=3+2+3=8
合法单词数:1≤n≤50;
每个单词长度:1≤lenwi≤50;
句子长度:1≤lens≤100;
所有单词和句子中的字符都是小写字母 (‘a’-‘z’)。

#include<iostream>
#include<algorithm>
#define oo 100000000
using namespace std;
int n ;
string ST ;
string st[1000] ;
int ch1[26] ,ch2[26] ;
int f[1000] ;
int Check( string test , int i ) {
    int sum = 0;
    int ln = test.size();
    for (int k = 0; k < 26; k++)
        ch1[k] = ch2[k] = 0;
    for (int j = i; j < i + ln; j++) {
        if (ST[j] != test[j - i]) sum++;
        ch1[test[j - i] - 'a']++;
        ch2[ST[j] - 'a']++;
    }
    for (int k = 0; k < 26; k++)
        if (ch1[k] != ch2[k]) {
            return oo;
        }
    return sum;
}
int main() {
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> st[i];
    cin >> ST;
    f[0] = 0;
    for (int i = 1; i < 1000; i++)
        f[i] = oo;
    for (int i = 0; i <= ST.size(); i++) {
        for (int j = 0; j <= n; j++)
            if (i + st[j].size() <= ST.size()) {
                f[i + st[j].size()] = min(f[i + st[j].size()], f[i] + Check(st[j], i));
            }
    }
    if (f[ST.size()] == oo) cout << "-1" << endl;
    else cout << f[ST.size()] << endl;
}

问题 E: Modulo Summation

题目描述

You are given N positive integers a1,a2,…,aN.
For a non-negative integer m, let f(m)=(m mod a1)+(m mod a2)+…+(m mod aN).
Here, X mod Y denotes the remainder of the division of X by Y.
Find the maximum value of f.
Constraints
·All values in input are integers.
·2≤N≤3000
·2≤ai≤105

输入

Input is given from Standard Input in the following format:
N
a1 a2 … aN

输出

Print the maximum value of f.
样例输入
3
3 4 6
样例输出
10

提示

f(11)=(11 mod 3)+(11 mod 4)+(11 mod 6)=10 is the maximum value of f.

#include<iostream>
#include<algorithm>
using namespace std;
int gcd(int a, int b)
{
    while (b)
    {
        int c = a;
        a = b;
        b = c%b;
    }
    return a;
}
long long gongbeishu(long long  a, long long b)
{
    lo 3ng long d = gcd(a, b);
    return a*b / d;
}
int main() {
    int n;
    long long x;
    cin >> n;
    int *a = new int[n];
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    x = a[0];
    for (int i = 1; i < n; i++) {
        x = gongbeishu(a[i], x);
    }
    x--;
    long long s = 0;
    for (int j = 0; j < n; j++)
        s += a[j]-1;
    cout << s;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值