3.21校赛

3.21校赛

A题目

题意

给出字符串,以标点符号为界,写成一个大写一个小写的形式

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 100003;
const int MAX = 1e3 + 10;
 
int main() {
    string str;
    cin >> str;
    int len = str.length();
    int cnt = 0;
    for(int i = 0; i < len; i++) {
        if(!isalpha(str[i])) {
            cnt = 0;
            printf("%c", str[i]);
        }
        else {
            cnt++;
            if(cnt % 2) printf("%c", toupper(str[i]));
            else printf("%c", tolower(str[i]));
        }
    }
}

H题目

题意

给n,S,(1 <= n <= 1000, 0 <= S <= 3000)问又多少中分法,使得数组a大小为n(ai为非负数,且不递减,总和为S),取模,MOD = 998255353

题解

其实,对于n个数,我只要取出每个ai的个数,就好了,因为排序规定了,

即对于不同的n个数,对于答案贡献为1,

那么,就可以忽略 数组内部不递减,这个条件

那么,问题就等价于S个数,分为n组,有几种分法

这就是计数DP板子题

啊,举个例子,S = 15, n = 5

1 2 3 4 5 和 5 4 3 2 1 是一样的(或者可以认为后面的忽略掉了

1 2 2 5 5 是不一样的

那只要考虑取出的数是不一样的排列,ans++

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 998244353;
const int MAX = 5e3 + 10;
int dp[MAX][MAX];

int main() {
    int n, V;
    scanf("%d%d", &n, &V);
    for(int i = 1; i <= n; i++) dp[i][0] = 1;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= V; j++) {
            if(j >= i) dp[i][j] = (dp[i - 1][j] + dp[i][j - i]) % MOD;
            else dp[i][j] = dp[i - 1][j] % MOD;
        }
    }
    printf("%d\n", dp[n][V] % MOD);
}

I题目

题意

给出两个字符串s,t,以及每一秒变化的数数组a, b(变化是指每一秒ai对应的si字典序加ai,but保证为小写字母(‘z’下面又是’a’)),问q次询问(q<=1e6),变化t(t<=1e18),问每次变化的最长公共子序列多长,s,t字符串字长1e3

题解

其实很简单,因为我注意到了t一定是要mod26的,26次以后就是一个循环

那么只要预处理一下就好了

我应该坚定的,LCS复杂度O(n^2),那么就1e6了,不可能再*q次询问的(主要是我记得好像有LCSo(n)的解法,误导我自己了,就算是这样1e9也不一定过的了

不对,1e9是铁T

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MOD = 100003;
const int MAX = 1e3 + 10;
char s[MAX], t[MAX];
int dp[30][MAX][MAX];
int len1, len2;
int a[MAX], b[MAX];
char s1[MAX], t1[MAX];
void solve() {
    for(int k = 0; k < 26; k++) {
        for(int i = 1; i <= len1; i++) s1[i] = (char) ('a' + (s[i] - 'a' + k * a[i]) % 26);
        for(int i = 1; i <= len2; i++) t1[i] = (char) ('a' + (t[i] - 'a' + k * b[i]) % 26);
        for(int i = 1; i <= len1; i++) {
            for(int j = 1; j <= len2; j++) {
                if(s1[i] == t1[j]) dp[k][i][j] = dp[k][i - 1][j - 1] + 1;
                else dp[k][i][j] = max(dp[k][i - 1][j], dp[k][i][j - 1]);
            }
        }
    }
}

int main() {
    int n, m;
    scanf("%d%d\n", &n, &m);
    scanf("%s\n", s + 1);
    scanf("%s\n", t + 1);
    len1 = strlen(s + 1);
    len2 = strlen(t + 1);
    for(int i = 1; i <= len1; i++) scanf("%d", &a[i]);
    for(int i = 1; i <= len2; i++) scanf("%d", &b[i]);
    solve();
    ll q;
    scanf("%lld", &q);
    while(q--) {
        ll t;
        scanf("%lld", &t);
        printf("%d\n", dp[t % 26][len1][len2]);
    }
}

J题目

题意

一个开关,有p(p = n / 1e4)的概率打卡,可以操作无限次,问最大的概率是多少

题解

p >= 0.5 ==> ans = p;

p >= 0 && p < 0.5 ==> ans = 0.5;

p = 0 ==> ans = 0;

《大胆猜测,小心求证》

(可以打一下前几项的概率,输入不同的值,其实是满足猜测的,就试试

《打表找规律》

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 100003;
const int MAX = 1e3 + 10;

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        double n;
        scanf("%lf", &n);
        double ans = 0;
        if(n == 0) ans = 0;
        else if(n >= 5000) ans = n / 10000;
        else ans = 0.5;
        printf("%.6lf\n", ans);
    }
}

C题目

题意

有n个人,每个人权重xi, 可以玩ai次,如果输了,就直接淘汰,如果两个人Pk,得到的权值li为xi ^ xj + xi + xj,问权值最大为多少

题解

可以将一个人分成两个点思考,对于i点所有可以击败的点j,连边流量为1,权值为xi ^ xj + xi + xj,源点S流向i点,如果i是最大的点,那么他可以赢ai次,流量为ai,否则一定会被打败一次,流量为ai - 1

对于点i来说,流入的代表可以赢的场次,能够流通的点,代表可以打败,上面还有费用权重,对于被打败的j点来说,流出的流量为1,代表输了一次就下场了

这样可以求最小费用流,问题是最大费用流,那么取反。

tips

我竟然不知道,^ 的 优先级 比 + 小(我还以为是一样的)

一 个 没 有 用 到 的 却 感 觉 比 较 有 用 的 知 识 点 : a + b = 2 ×   ( a & b ) + a   x o r   b ; \color{blue}一个没有用到的却感觉比较有用的知识点: a + b = 2 \times\ (a \& b) + a \ xor\ b; :a+b=2× (a&b)+a xor b;
a   x o r   b + a & b = a ∣ b \color{blue}a\ xor \ b + a \& b = a | b a xor b+a&b=ab

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAX = 2e6 + 10;
#define SZ(v) (int)v.size()
#define pii pair<ll,ll>

const ll INF = 0x3f3f3f3f;
const ll MAXN = 2e6 + 10;

struct MCMF {
    struct Edge {
        ll v, cap, cost, rev;
        Edge(ll v, ll cap, ll cost, ll rev):v(v),cap(cap),cost(cost),rev(rev){}
    };

    ll flow, cost, s, t, n;
    ll dist[MAXN], H[MAXN], pv[MAXN], pe[MAXN];
    std::vector<Edge> G[MAXN];

    bool dijkstra() {
        std::priority_queue<pii, std::vector<pii>, std::greater<pii> > q;
        std::fill(dist, dist + n + 1, INF);
        dist[s] = 0; q.push({0, s});
        while (!q.empty()) {
            pii x = q.top(); q.pop();
            ll &u = x.second;
            if (dist[u] < x.first) continue;
            for (int i = 0; i < SZ(G[u]); ++i) {
                Edge &e = G[u][i];
                ll &v = e.v;
                pii y(dist[u] + e.cost + H[u] - H[v], v);
                if (e.cap > 0 && dist[v] > y.first) {
                    dist[v] = y.first;
                    pe[v] = i, pv[v] = u;
                    q.push(y);
                }
            }
        }

        if (dist[t] == INF) return false;
        for (int i = 0; i <= n; ++i) H[i] += dist[i];

        ll f = INF;
        for (int v = t; v != s; v = pv[v]) f = std::min(f, G[pv[v]][pe[v]].cap);

        flow += f;
        cost += f * H[t];

        for (int v = t; v != s; v = pv[v]) {
            Edge &e = G[pv[v]][pe[v]];
            e.cap -= f;
            G[v][e.rev].cap += f;
        }

        return true;
    }

    void solve(int s, int t) {
        this->s = s, this->t = t;
        flow = cost = 0;
        std::fill(H, H + n + 1, 0);
        while (dijkstra());
    }

    void init(int n) {
        this->n = n;
        for (int i = 0; i <= n; ++i) G[i].clear();
    }

    void add_edge(ll u, ll v, ll cap, ll cost) {
        G[u].push_back(Edge(v, cap, cost, SZ(G[v])));
        G[v].push_back(Edge(u, 0, -cost, SZ(G[u]) - 1));
    }

} mcmf;
ll x[MAX];
ll a[MAX];

int main() {
    ll n;
    scanf("%lld", &n);
    ll s = 2 * n + 1, t = s + 1;
    mcmf.init(t);
    int posmax = 0;
    ll maxx = -1;
    for(int i = 0; i < n; i++) {
        scanf("%lld%lld", &x[i], &a[i]);
        if (x[i] > maxx) {
            maxx = x[i];
            posmax = i;
        }
        mcmf.add_edge(s, i, a[i] - 1, 0);
        mcmf.add_edge(i + n, t, 1, 0);
    }
    mcmf.add_edge(s, posmax, 1, 0);
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if(x[i] > x[j]) {
                ll cost = (x[i] ^ x[j])  + (x[i] + x[j]);
                //ll cost = (x[i] | x[j]) * 2;
                mcmf.add_edge(i, j + n, 1, -cost);
            }
        }
    }
    mcmf.solve(s, t);
    ll ans = mcmf.cost;
    printf("%lld\n", -ans);
}

个人总结

我发现了我的舒适点, 还有薄弱点( 这周发现的)
即绕好几个弯的思维题( 优化题面, 简化问题) , ( 校赛证明DP 我还是可以出的嘛
我的缺点是读题太差( 且不是很愿意读题, 开新的题目, 在后两个小时最为明显)
后劲不足, 两小时后就不去思考了
图论这块差( 按照知识点来说

团队总结

( 校赛第七名, 除去打星

总的来说, 比较幸运。

( 我们前6 题, 只PE 了一次( 十分可惜, 如果正式比赛有热身赛, 就可以试错规避) , 罚时较少

后面出了G 题, 属于较难题目, 且比赛后半段思维感觉不是很活跃

优点是罚时少, 简单题目出题比较稳且快

缺点是, 确实能力有限, 难题不会写, 较高强度思考使得脑子太快糊掉了( 要多进行长时间的训练

经验:

不一定要跟榜, 可以先随意开, 有思路就试一试, 就比如说开了H 题, 果断试了一下, 过了( 感觉信心也+ + 了

注重cin cout 的关闭同步流, 不能因为这个T , 造成罚时

交流大声一点, 确保队友有效交流

对于不确定的题目( 指的是不能严格证明, but 大致推测除了规律的题目) , 和队友交流一下, 感觉没有问题, 就冲

善用打表看规律( 适于是在出不了题目的情况), 其实E 题会发现3 * c * c 无解, 2 * c * c 解是c * c 的解法+ 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值