首页 > 其他分享 >24/8/12 模拟赛

24/8/12 模拟赛

时间:2024-08-12 19:52:00浏览次数:18  
标签:24 12 int void memset add maxN 模拟 dis

hz暑假集训 8/12

数字三角形

CF1517C
签到题。

题意:
小 \(D\) 给你一个长度为 \(n\) 的排列 \(p\) ,你需要根据 \(p\) 构造出一个三角形。
该图案需要满足共 \(n\) 行,第 \(i\) 行有 \(i\) 个数,第 \(i\) 行最后一个数是 \(p_i\)。
数值 \(p_i\) 有 \(p_i\) 个且四联通。
几个位置是四联通的,是指从其中某个位置出发,只往上下左右走,只经过这些位置,可以到达其中任意一个位置。

思路:
每个数向左扩展,然后向下扩展。

5 
5 1 4 2 3

5
5 1
5 4 4
5 4 3 3
5 4 3 2 2

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxN = 507;

int n, p[maxN];
int a[maxN][maxN];

void dfs(int x, int y, int num, int stp) {
    if (!stp) return;
    a[x][y] = num;
    if (!a[x][y - 1])
        dfs(x, y - 1, num, stp - 1);
    else
        dfs(x + 1, y, num, stp - 1);
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);

    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> p[i];
    for (int i = 1; i <= n; i++)
        a[i][0] = -1;
    for (int i = 1; i <= n; i++)
        dfs(i, i, p[i], p[i]);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++)
            cout << a[i][j] << ' ';
        cout << '\n';
    }
}

那一天她离我而去

题意:无向图找出从 1 到 1 的最小环长度。无重边 无自环

思路:
首先考虑暴力,从 1 出发经历一条边到的每个点放到一个数组,\(n^2\) 枚举起点终点跑最短路,再加上 1 到这两个点的距离。

正解非常巧妙,二进制拆分,分别考虑每一位,是 0 的看成起点,是 1 的看成终点,在建超级源点(niubi源点)连每一个起点,边权为 $1 \to x $ 的边权;每一个终点连超级汇点,边权为 \(x \to 1\) 的边权。跑最短路即可。
因为俩个不同的点二进制下一定最少一位不同,所以每个点都会分别被分到起点,终点,所以不漏。

代码:

#include <bits/stdc++.h>

using namespace std;

const int maxN = 1e4 + 7, maxM = 6e4;

struct node {
    int x, hx;
};
vector<node> D;

int head[maxN], tot;
struct edge {
    int ls, to, w;
} e[maxM << 1];
void add(int x, int y, int z, bool record) {
    if (record)
        D.push_back({x, head[x]});
    e[++tot] = {head[x], y, z};
    head[x] = tot;
}

void cancel() {
    while (!D.empty()) {
        auto tp = D.back();
        D.pop_back();
        tot--;
        head[tp.x] = tp.hx;
    }
}

int ans;
int n, m;

int dis[maxN];
bool vis[maxN];
priority_queue<pair<int, int>> q;
void dij(int S) {
    for (int i = 0; i <= n + 1; i++)
        dis[i] = 1e9, vis[i] = false;
    dis[S] = 0;
    q.push({0, S});
    while (!q.empty()) {
        int f = q.top().second;
        q.pop();
        if (vis[f]) continue;
        vis[f] = true;
        for (int i = head[f]; i; i = e[i].ls) {
            int to = e[i].to;
            if (dis[to] > dis[f] + e[i].w) {
                dis[to] = dis[f] + e[i].w;
                q.push({-dis[to], to});
            }
        }
    }
}

vector<pair<int, int>> A;

void solve() {
    cin >> n >> m;
    
    A.clear();
    ans = 1e9;
    tot = 0;
    for (int i = 0; i <= n + 1; i++)
        head[i] = 0;

    for (int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        if (u > v) swap(u, v);
        if (u == 1)
            A.push_back({v, w});
        else {
            add(u, v, w, false);
            add(v, u, w, false);
        }
    }
    
    for (int i = 13; i >= 0; i--) {
        for (auto t : A) {
            int fi = t.first, se = t.second;
	        if ((fi >> i) & 1)
                add(0, fi, se, true);
            else 
                add(fi, n + 1, se, true);
        }
        dij(0);
        ans = min(ans, dis[n + 1]);

        cancel();
    }

    if (ans >= 1e9)
        cout << "-1\n";
    else
        cout << ans << '\n';
}

int main() {
    // freopen("leave.in", "r", stdin);
    // freopen("b.txt", "w", stdout);
    ios::sync_with_stdio(false), cin.tie(nullptr);

    int T;
    cin >> T;
    while (T--)
        solve();
}

话说好像好多届都考过这个题了, 网上有学哥的博客。

哪一天她能重回我身边

题意:有 \(n\) 张牌,牌正面是 \(a\),反面是 \(b\),初始都是正面。求最小的翻转的次数,使牌上面的数互不相同,以及最少翻转达成目标的方案数。

图论题。。。
很巧妙的建图方法,从每张牌的正面向反面连边。发现方案合法为每个点出度小于等于 1 时。
翻转相当于把有向边翻转。
然后发现对于一个联通块合法其实就是树或基环树。

对于树,就可以考虑换根dp,设 \(g[x]\) 表示以 \(x\) 为根的最小翻转数,那么如果有一条边是 \(x\to to\),\(g[to] = g[x] - 1\),如果是 \(to\to x\),就是 \(g[to] = g[x] + 1\)。
每个联通块内的最小 \(g[x]\) 之和就是最总答案,第二问顺便处理一下就好了。

对于基环树,断掉环上的一条边跑树的情况。最后分讨一下边的方向就可以了。

思路比较难想,代码我选择贺(。

// 抄的学哥的
#include <bits/stdc++.h>

using namespace std;

#define int long long

const int maxN = 2e5 + 7, mod = 998244353;

int n;

struct edge {
    int ls, to, w, st;
} e[maxN << 1];
int head[maxN], tot;
void add(int u, int v, int w) {
    e[++tot] = {head[u], v, w, u};
    head[u] = tot;
}

int np, ne;
bool v[maxN], vi[maxN];
void dfs(int x, int f) {
    vi[x] = true;
    np++;
    for (int i = head[x]; i; i = e[i].ls) {
        ne++;
        if (e[i].to == f || vi[e[i].to]) continue;
        dfs(e[i].to, x);
    }
}
bool pd() {
    for (int i = 1; i <= n * 2; i++)
        if (!vi[i]) {
            np = ne = 0;
            dfs(i, 0);
            if (np < ne / 2)
                return true;
        }
    return false;
}
int f[maxN], S, T, ned;
void dfs1(int x, int fa) {
    v[x] = true;
    f[x] = 0;
    for (int i = head[x]; i; i = e[i].ls)
        if (e[i].to != fa) {
            if (!v[e[i].to]) {
                dfs1(e[i].to, x);
                f[x] += f[e[i].to] + e[i].w;
            }
            else
                S = e[i].st, T = e[i].to, ned = i;
        }
}
int g[maxN];
vector<int> tem;
void dfs2(int x, int fa) {
    tem.push_back(g[x]);
    for (int i = head[x]; i; i = e[i].ls)
        if (e[i].to != fa && i != ned && i != (ned ^ 1)) {
            if (e[i].w) g[e[i].to] = g[x] - 1;
            else g[e[i].to] = g[x] + 1;
            dfs2(e[i].to, x);
        }
}

void solve() {
    tot = 1;
    memset(f, 0, sizeof(f));
    memset(g, 0, sizeof(g));
    memset(v, 0, sizeof(v));
    memset(vi, 0, sizeof(vi));
    memset(head, 0, sizeof(head));
    tem.clear();

    cin >> n;
    for (int i = 1; i <= n; i++) {
        int a, b;
        cin >> a >> b;
        add(a, b, 1), add(b, a, 0);
    }
    if (pd())
        return cout << "-1 -1\n", void();
    
    int ans = 0;
    int minn = 0, ans2 = 1;
    for (int i = 1; i <= n * 2; i++)
        if (!v[i]) {
            S = T = ned = -1;
            tem.clear();
            minn = 0;
            dfs1(i, 0);
            g[i] = f[i];
            dfs2(i, 0);
            if (S == -1) {
                sort(tem.begin(), tem.end());
                for (unsigned j = 0; j < tem.size(); j++)
                    if (tem[j] == tem[0])
                        minn++;
                    else break;
                ans += tem[0];
            }
            else {
                ned %= 2;
                if (g[S] + ned == g[T] + (ned ^ 1))
                    minn = 2;
                else
                    minn = 1;
                ans += min(g[S] + ned, g[T] + (ned ^ 1));
            }
            ans2 = ans2 * minn % mod;
        }
    cout << ans << ' ' << ans2 << '\n';
}

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);

    int Tim;
    cin >> Tim;
    while (Tim--)
        solve();
}

T4 不会

标签:24,12,int,void,memset,add,maxN,模拟,dis
From: https://www.cnblogs.com/ccxswl/p/18355605

相关文章

  • 报错:2024-08-12T18:39:35.313+08:00 ERROR 29668 --- [demo2] [ main] o.s.
    org.springframework.beans.factory.BeanDefinitionStoreException:Failedtoparseconfigurationclass[com.example.demo.DemoApplication]atorg.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:179)~[spring-con......
  • ClueCon 2024:音视频开发者的技术盛会
       前面的话:ClueCon是音视频开发者的年度技术盛会,每年都在美国芝加哥举行。RTE开发者社区的联合主理人杜金房在即将踏上ClueCon之际,写下了这段文字。也邀请大家一同关注这次大会。 时间过得真快,转眼,又是一届新的ClueCon了。 ClueCon是一个音视频开发者的年度......
  • 2024华为OD笔试机试 - 模拟目录管理功能 (python/c++/java D卷C卷真题算法)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。支持命令:创建目录命令:mkdir目录名称,如mkdirabc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作。此命令无输出......
  • 《分析模式》2024中译本前言01
    前言不久前,还没有关于面向对象分析和设计的书籍。现在,这类书籍多到任何从业者都无法全部跟上。大多数这些书籍专注于教授一种表示法,提出一种简单的建模过程,并用几个简单的例子来说明。《分析模式:可复用的对象模型》是一本不同类型的书。它不聚焦于过程——如何做建模,而是专注......
  • 软件著作权申请教程(超详细)(2024新版)软著申请
        目录一、注册账号与实名登记二、材料准备三、申请步骤1.办理身份2.软件申请信息3.软件开发信息4.软件功能与特点5.填报完成一、注册账号与实名登记    首先我们需要在官网里面注册一个账号,并且完成实名认证,一般是注册【个人】的身份。中国版权保护......
  • [赛记] 暑假集训CSP提高模拟19
    数字三角形100pts原题:LuoguCF1517CFillomino2贪心的想一想,我们从上往下处理每个数,每次向左走,不行再向右走,这样就行(因为右面一定有地方,但我们要尽量留给下一个数);为什么这样能填满?下面给出证明:首先,右面和下面不会有空缺(填的方向就是右面和下面);然后手模一下,我们会发现,其实每......
  • 124. 项目74:简易句子结构分析器——《跟老吕学Python·新手》
    124.项目74:简易句子结构分析器——《跟老吕学Python·新手》124.项目74:简易句子结构分析器124.1目标124.2功能124.3设计124.4实现步骤124.5代码实现124.6测试124.7注意事项124.8小结124.项目74:简易句子结构分析器124.1目标开发一个......
  • 2024年华为OD机试真题-模拟数据序列化传输-Java-OD统一考试(C卷)
    2024年OD统一考试(D卷)完整题库:华为OD机试2024年最新题库(Python、JAVA、C++合集) 题目描述:模拟一套简化的序列化只传输方式,请实现下面的数据编码与解码过程1、编码前数据格式为[位置,类型,值],多个数据的时候用逗号分隔,位置仅支持数字,不考虑重复等场景;类型仅支持:Integer......
  • 学习AGI大模型在2024年到底有多重要?
    前言随着科技的飞速发展,我们正处在一个智能化的时代。2024年,AGI(人工通用智能)大模型即将成为改变我们生活的重要力量。它不仅将引领科技产业的变革,还将为我们的日常生活带来巨大的影响。大模型的牛X之处在哪里?AGI大模型将极大地提升我们的工作效率。想象一下,一个能够理解......
  • 达梦数据库系列—47.DMHS实现Oracle12C到DM8的同步
    目录1、准备介质2、安装3、准备源端Oracle和目标端DM8软件安装数据库创建打开归档开启附加日志创建辅助表Oracle端安装ODBC创建连接用户创建测试用户和表4、同步配置修改服务配置Oracle到Dm单向同步配置Dm到Oracle单向同步配置5、启动DMHS服务初始装载装载数......