SDUT 2023 summer team contest(for 22) - 12

A - Today's Word

 题意:就是给你一个字符串S0,让你输出S10^{100}的后m位是什么,

思路:我们知道Sn=Sn-1的前一半+Sn-1+next(Sn-1的后一半的后一位,z的后一位是a),next是求其下一位(z的下一位是a),我们可以知道当Sn的的长度大于2*m时,答案只会是其后缀的变换,10^{100}%26==16

故我们只需要将其长度变到大与2*m后,进行next变换即可

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 1e6 + 7, P = 13331;
const double eps = 1e-8;
int n, m;
string s;
string now, p, str;
string fun(string ss)
{
    for (int i = 0; i < ss.size(); i++)
    {
        if (ss[i] != 'z')
            ss[i]++;
        else
            ss[i] = 'a';
    }
    return ss;
}
void solve()
{
    cin >> n >> m;
    cin >> s;
    p = s;
    now = s;
    int len = n;
    int cnt = 0;
    for (int i = 1;; i++)
    {
        p.clear();
        p += now.substr(0, len / 2);
        p += now;
        p += fun(now.substr(len / 2));
        len = p.size();
        now = p;
        cnt = i;
        if (p.size() / 2 >= m)
        {
            str = p.substr(len - m);
            break;
        }
    }
    string ans = str;
    int x=16;
    while(x<=cnt)//炒作次数可能大于16,那我们就加上26这个循环节即可
    x+=26;
    for (int i = 1; i <= x - cnt; i++)
    {
        ans = fun(str);
        str = ans;
    }
    cout << ans << endl;
}
signed main()
{
    Ysanqian;
    int T;
    T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}

F - Timaeuszf

题意:你有 A个原料,每 B个合成一个产品。(这题当时也没想出来,看了看巨佬的

每一次合成你可以选择下列两种 buff的任意一种:

1 : P% 的概率合成双倍产物
2 : Q% 的概率返还一个原料
求期望最多合成多少产物。

思路
设 dp(i)表示还剩下  i 个原料时的最大期望。

显然可以转移到dp(i)的有两个大事件,两个大事件有分成功不成功,小事件的和对应大事件

1:当B⩾2时,

dp[i]=max( P×(dp[i−B]+2)+(1−P)×(dp[i−B]+1) , Q×(dp[i−B+1]+1)+(1−Q)×(dp[i−B]+1) ).

2:当B=1时,选择第一种方法

dp[i]=P×(dp[i−1]+2)+(1−P)×(dp[i−1]+1)

选择第二种方法(代入上面的式子,发现存在自环依赖,左边有dp[i],右边也有dp[i],需要整理表达式):

dp[i]=Q×(dp[i]+1)+(1−Q)×(dp[i−1]+1)

dp[i]=Q×dp[i]+Q+(1−Q)×dp[i−1]+(1−Q)

(1−Q)×dp[i]=(1−Q)×dp[i−1]+1

dp[i]=dp[i−1]+11−Q

由上述式子得(已知dp[0]=0): dp[i]=dp[0]+i×d=0+i×11−Q=i1−Q

两者取最大值即可.

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 1e6 + 7, P = 13331;
const double eps = 1e-8;
int a, b;
double p, q;
double f[N];
void solve()
{
    cin >> a >> b >> p >> q;
    q = 1.0 * q / 100;
    p = 1.0 * p / 100;
    for (int i = b; i <= a; i++)
        if (b == 1)
            f[i] = max(p * (f[i - 1] + 2) + (1 - p) * (f[i - 1] + 1), 1.0 * i / (1 - q));
        else
            f[i] = max(p * (f[i - b] + 2) + (1 - p) * (f[i - b] + 1), q * (f[i - b + 1] + 1) + (1 - q) * (f[i - b] + 1));
    printf("%.15lf\n", f[a]);
}
signed main()
{
    Ysanqian;
    int T;
    T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}

J - Similarity (Easy Version)

思路:纯暴力即可

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 1e6 + 7, P = 13331;
const double eps = 1e-8;
int n;
string s[N];
int ans;
void check(string a, string b)
{
    for (int i = 0; i < a.size(); i++)
    {
        for (int j = 0; j < b.size(); j++)
        {
            if (a[i] != b[j])
                continue;
            int l = i, r = j;
            while (l < a.size() && r < b.size())
            {
                if (a[l] != b[r])
                    break;
                l++, r++;
            }
            ans = max(r -j, ans);
        }
    }
}
void solve()
{
    ans = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> s[i];
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
            check(s[i], s[j]);
    cout << ans << endl;
}
signed main()
{
    Ysanqian;
    int T;
    // T = 1;
    cin >> T;
    while (T--)
        solve();
    return 0;
}

K - Similarity (Hard Version)

题意:给你三个数,n,m,k,分别是需要构造的数量,最大相识度,每一个的长度

让你输出是否可以构造出这么多

思路:首先就是先看特判情况

1:①m==0,n>26;②m!=0,m>=k

有解情况

2:①m==0,输出长度为k的全由第i个小写字母组成的串即可

②m!=0,前面先构造长度为m-1的a串(相似部分),后面考虑构造abab,acaca....azaz,bcbc,bdbd..bzbz,cdcd,这种方法共有25*(25-1)/2==300,正好满足题意

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 1e6 + 7, P = 13331;
const double eps = 1e-8;
int n, m, k;
string shift(string s, int idx, int tag)
{
    if (idx == 1)
        return s;
    for (int i = 0; i < s.size(); i++)
    {
        if (tag == 1 && i % 2)
            s[i]++;
        if (tag == 2)
        {
            if (!(i % 2))
                s[i]++;
            else
                s[i] = s[i - 1];
        }
    }
    return s;
}
void solve()
{
    cin >> n >> m >> k;
    if (m == 0)
    {
        if (n > 26)
            cout << "No" << endl;
        else
        {
            cout << "Yes" << endl;
            char s = 'a';
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= k; j++)
                    cout << s;
                s++;
                cout << endl;
            }
        }
    }
    else
    {
        if (m >= k)
            cout << "No" << endl;
        else
        {
            cout << "Yes" << endl;
            string p, s, backup;
            for (int i = 1; i < m; i++)
                p += "a";
            for (int i = 1; i <= k - m + 1; i++)
            {
                if (i % 2)
                    s += "a";
                else
                    s += "b";
            }
            backup = s;
            for (int i = 1; i <= n; i++)
            {
                s = shift(s, i, 1);
                cout << p << s << endl;
                if (s[1] == 'z')
                {
                    s = backup;
                    s = shift(s, i, 2);
                    backup = s;
                }
            }
        }
    }
}
signed main()
{
    Ysanqian;
    int T;
    T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}

H - Neil's Machine

 题目:有两个长度为 n  只存在小写字母的字符串 s,t 。每次操作可 以选择一个正数 k (1 ≤ k ≤ 25), 并选择 S 的一个后缀在字母表的位置后移动 k位 ,问至少几次操作可以令 s=t 。

思路:偏移量有点不是很熟,就直接模拟了毕竟每次就改一个,时间也没问题

#include <bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define xx first
#define yy second
#define endl "\n"
#define lowbit(x) x & (-x)
#define int long long
#define ull unsigned long long
#define pb push_back
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define Ysanqian ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 1e6 + 10, M = 1010, inf = 0x3f3f3f3f, mod = 1e6 + 7, P = 13331;
const double eps = 1e-8;
int n, now, ans;
string a, b;
char fun(char p)
{

    if (p + now <= 'z')
        p = p + now;
    else
        p = 'a' + now - 1 - ('z' - p);
    return p;
}
void solve()
{
    cin >> n;
    cin >> a >> b;
    for (int i = 0; i < n; i++)
    {
        if (a[i] != fun(b[i]))
        {
            ans++;
            if (a[i] >= b[i])
                now = a[i] - b[i];
            else
                now = 26 + a[i] - b[i];
        }
    }
    cout << ans << endl;
}
signed main()
{
    Ysanqian;
    int T;
    T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值