Codeforces Round #786 (Div. 3) A - F 题解

Codeforces Round #786 (Div. 3)#

今天五一集训第三天,找时间把集训的模拟赛整理一下,今晚有div3打星,就来瞧一瞧是啥题

A. Number Transformation#

题目大意:给出两个数 x 和 y,问两个值 a 和 b,使得xba=y

直接让 a = 1,如果 y % x = 0,则 b 就是 y / x,否则就无答案

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int x, y;
        cin >> x >> y;
        if(y % x == 0)
        {
            cout << 1 << " " << y / x << endl;
        }
        else
            cout << 0 << " " << 0 << endl;
    }

    return 0;
}

B. Dictionary#

题目大意:定义字符串的编号,输入字符串,求编号

直接预处理一下字符串对应的编号,输出即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
map<string, int>vis;
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;

int main()
{
    int t;
    cin >> t;
    int tp = 0;
    for(int i='a'; i<='z'; i++)
    {
        for(int j='a'; j<='z'; j++)
        {
            if(i == j) continue;
            string now = "";
            now += i;
            now += j;
            vis[now] = ++tp;
        }
    }
    while(t--)
    {
        string s;
        cin >> s;
        cout << vis[s] << endl;
    }
    return 0;
}

C. Infinite Replacement#

题目大意:给出两个串 s 和 t,s 仅由若干个 a 组成,t任意,可以将 s 中任意一个 a 替换成字符串 t,问能得到多少种不同的字符串

  • 如果 t 为字符串 "a", 则答案是 1

  • 如果 t 中有 a 字符存在,且 |t|>1,则可以无限替换

  • 如果没有 a 存在,那么对于 s 中每个字符可以选择替换或者不替换,那么就是 2|s| 中字符串,|s| 表示 s 的串长

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
map<string, int>vis;
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll init[maxn];

int main()
{
    int t;
    cin >> t;
    init[0] = 1;
    for(int i=1; i<=50; i++) init[i] = 2 * init[i-1];
    while(t--)
    {
        string s, t;
        cin >> s >> t;
        int f = 0;
        for(int i=0; i<t.size(); i++)
            if(t[i] == 'a') f++;
        ll ans = 0;
        if(f == t.size() && f == 1) ans = 1;
        else if(f && t.size() >= 2) ans = -1;
        else
            ans = init[s.size()];
        cout << ans << endl;
    }
    return 0;
}

D. A-B-C Sort#

我们可以发现从数组 a 添加数字到数组 b 时,每添加两个后,再添加时,就会把先前添加的两个挤到边缘去

同理 b 数组转移到 c 数组的时候,也是可视为两个两个地添加

而且 a 数组在改变为的时候是从后往前拿的,因此我们可以得出,a 数组从后往前数,每两个一组,我们可以改变组内的相对位置

最后判断是否不递减就行

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn];

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d", &n);
        for(int i=0; i<n; i++) scanf("%d", &num[i]);
        for(int i=n-2; i>=0; i-=2) if(num[i] > num[i+1]) swap(num[i], num[i+1]);
        int f = 1;
        for(int i=1; i<n && f; i++)
            if(num[i] < num[i-1]) f = 0;
        printf("%s\n", f ? "YES" : "NO");
    }

    return 0;
}

E. Breaking the Wall#

这题原来的数据太弱了,最后我被hack了

总共要跑四次暴力

  • 选出最薄弱的两个,然后不断 -2

  • 遍历所有相邻的,用攻击一个 -2,然后溅射另一个 -1 的方式,或者是任意组合,组合到最优即可

  • 遍历所有中间隔着一个的,不断地攻击中间那个,使得两边不断 -1

  • 遍历所有中间隔着一个的,先攻击一次中间那个,再攻击两边的 -2,例如: 3 10000 5

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[maxn];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=0; i<n; i++) scanf("%d", &num[i]);
    int minn = 1e6 + 10, way = 0;
    for(int i=0; i<n; i++)
    {
        if(minn > num[i])
        {
            minn = num[i];
            way = i;
        }
    }
    int minnn = 1e6 + 10;
    for(int i=0; i<n; i++)
    {
        if(way == i) continue;
        minnn = minnn < num[i] ? minnn : num[i];
    }
    int ans = (minn + 1) / 2 + (minnn + 1) / 2;
    for(int i=1; i<n; i++)
    {
        int temp = 0;
        int a = min(num[i], num[i-1]);
        int b = max(num[i], num[i-1]);
        if(b >= a * 2)
            temp = (b + 1) / 2;
        else
            temp = (a + b + 2) / 3;
        ans = temp < ans ? temp : ans;
    }
    for(int i=1; i<n-1; i++)
        ans = min(max(num[i-1], num[i+1]), ans);
    for(int i=2; i<n; i++)
        ans = min(ans, 1 + num[i] / 2 + num[i-2] / 2);
    printf("%d\n", ans);
    return 0;
}

F. Desktop Rearrangement#

这题纯纯恶心人,每次修改都要O(1),出结果

题目大概就是说,把所有的星号(*),按照列的顺序,从左边列开始,一个个地排列下来,问需要移动多少个星号,题目给出的询问就是将给出的坐标的状态转换,点改成星号,星号改成点

就先从给出的图里面看看要排列到哪一个位置,每次的状态改变都只要讨论两个东西:

  1. 最终排列位置少一个或多一个对答案的影响

  2. 这次状态改变的地方是否需要额外加一次,或者减一次

分开两种状态改变进行讨论即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 1010;
const ll inf = 1e17 + 10;
char s[maxn][maxn];

int main()
{
    int n, m, q;
    scanf("%d%d%d", &n, &m, &q);
    for(int i=0; i<n; i++) scanf("%s", s[i]);
    int cnt = 0;
    for(int i=0; i<n; i++) for(int j=0; j<m; j++) if(s[i][j] == '*') cnt++;
    int temp = cnt;
    int x = 0, y = 0;
    for(int i=0; i<temp; i++)
    {
        if(s[x][y] == '*') cnt--;
        x++;
        if(x == n)
        {
            x = 0;
            y++;
        }
    }
    while(q--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        a--, b--;
        if(s[a][b] == '*')
        {
            x--;
            if(x == -1)
            {
                x = n - 1;
                y--;
            }
            if(s[x][y] == '*') cnt++;
            s[a][b] = '.';
            if(b > y || (b == y && a >= x)) cnt--;
        }
        else
        {
            if(s[x][y] == '*') cnt--;
            s[a][b] = '*';
            x++;
            if(x == n)
            {
                x = 0;
                y++;
            }
            if(b > y || (b == y && a >= x)) cnt++;
        }
        printf("%d\n", cnt);
    }
    return 0;
}

G. Remove Directed Edges

这题有机会就补了,听说是个拓扑 + dp ?

比赛时看完题倒是没有什么头绪

posted @   dgsvygd  阅读(180)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示
主题色彩