7-7 与零交换

给定排列\(p:0,1,2...n-1\),每次操作你只能将一个数字和\(0\)进行交换,然后将初始排列升序排列,请你找出最少的与\(0\)交换的次数

题解:思维 + 环

  • 样例一: \(4,0,1,2,3\)
  • 我们观察位置 \(0,1,2,3,4\) 发现形成了\(0->1->2->3->4\)的环,那么交换次数就是环的长度-1,即\(n-1\)
  • 那么如果一个环中不存在\(0\),我们实际上可以先将\(0\)交换进去,答案贡献加1,然后现在环的长度+1,所以最后该环的交换次数为\(n+1\)
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10; int n;
int a[N];
int vis[N];
int pos[N]; void solve()
{
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> a[i];
pos[a[i]] = i;
}
int ans = 0;
for (int i = 0; i < n; ++i)
{
if (!vis[a[i]])
{
map<int, int> mp;
int p = a[i];
while (!vis[p])
{
vis[p] = 1;
mp[p]++;
p = pos[p];
}
if (mp.count(0) && mp.size() > 1)
ans += mp.size() - 1;
else if (mp.size() > 1)
ans += mp.size() + 1;
}
}
cout << ans << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}

7-8 出栈序列的合法性

给定一个最大容量为 M 的堆栈,将 N 个数字按 1, 2, 3, ..., N 的顺序入栈,允许按任何顺序出栈 ,给出\(q\)次询问,每次回答给定的出栈序列是否合法

题解:模拟栈 \(O(n)\)

首先出栈的顺序存在三种情况:

  1. 一入栈就出栈,例如:1 2 3
  2. 入栈几次后再出栈,例如:3 2 1
  3. 前面两种情况的复合情况

对于本题我们只需模拟栈即可,因为一个数字如果要出栈,说明这个数字之前的所有数字都已经入栈过一次了,利用该性质我们利用栈模拟该过程即可;我们发现每个数字只会被入栈和出栈依次,所以查询一次的复杂度为\(O(n)\)

#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10; int m, n, q;
int stk[N], tt;
int a[N]; void solve()
{
cin >> m >> n >> q;
while (q--)
{
int flag = true;
tt = 0;
for (int i = 1; i <= n; ++i)
cin >> a[i];
int pre = 1;
for (int i = 1; i <= n; ++i)
{
if (tt == 0)
{
for (int j = 1; j <= a[i]; ++j)
stk[++tt] = j;
if (tt > m)
{
flag = false;
break;
}
pre = a[i];
tt--;
}
else if (tt && pre < a[i])
{
for (int j = pre + 1; j <= a[i]; ++j)
stk[++tt] = j;
if (tt > m)
{
flag = false;
break;
}
pre = a[i];
tt--;
}
else if (tt && pre > a[i])
{
if (stk[tt] != a[i])
{
flag = false;
break;
}
tt--;
}
}
if (flag)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}

7-12 肿瘤诊断

给定\(L\)层切片,每层切片大小为\(N×M\),体积限制为\(T\),每层切片只由0和1组成,让你数所有切片中形成的连通块中1的数量,如果该连通块中1的数量少于\(T\),则不计入答案,六个面中只要有一个面存在1就能说明两个1连通

题解:三维\(BFS\)

三维\(BFS\)板子题,当时没理解题意,没看出来是三维,裂开

#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10; int n, m, L, limit;
int g[65][1300][135];
bool vis[65][1300][135];
int dir[6][3] = {{0, 0, -1}, {0, 0, 1}, {0, -1, 0}, {0, 1, 0}, {1, 0, 0}, {-1, 0, 0}};
int ans; struct node
{
int k, x, y;
}; void bfs(int k, int x, int y)
{
queue<node> q;
q.push({k, x, y});
vis[k][x][y] = true;
int res = 0;
while (q.size())
{
node u = q.front();
q.pop();
res++;
for (int i = 0; i < 6; ++i)
{
int nk = u.k + dir[i][0];
int nx = u.x + dir[i][1];
int ny = u.y + dir[i][2];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && nk >= 1 && nk <= L && !vis[nk][nx][ny] && g[nk][nx][ny] == 1)
{
vis[nk][nx][ny] = true;
q.push({nk, nx, ny});
}
}
}
if (res >= limit)
ans += res;
} void solve()
{
cin >> n >> m >> L >> limit;
for (int k = 1; k <= L; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin >> g[k][i][j];
for (int k = 1; k <= L; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
{
if (!vis[k][i][j] && g[k][i][j] == 1)
bfs(k, i, j);
}
cout << ans << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}

7-13 凑零钱

一个人手里有\(10^4\)枚硬币,每种硬币只能用\(1\)次,需要请你帮她盘算一下,是否可能精确凑出要付的款额\(m\),输出字典序最小的方案

题解:贪心 + 变种\(01\)背包求方案 / \(DFS\)回溯

方法1:\(dp\)

  1. 状态表示:\(f[i]\):精准凑出金额\(i\)的钱最多需要几个硬币
  2. 状态属性:\(MAX\)
  3. 状态转移:转移的前提是前一个状态必须是合法的(也就是说前一个状态代表的金额能被硬币凑出)\(f[j] = max(f[j],f[j-a[i]]+1)\ \&\& \ (f[j-a[i]]>0\ ||\ j-a[i]==0)\)
  4. 状态初始:\(f[i]=0\)
  5. 答案呈现:如果\(f[m]>0\),代表金额\(m\)能被精准凑出,我们利用\(vector\)记录方案即可
  6. 如何求字典序最小的方案:贪心,将硬币升序排列即可,这样记录的方案一定是字典序最小的

方法2:\(dfs\)搜索

​ 贪心升序排序后\(dfs\)爆搜即可

//dp
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10; int n, m;
int a[N];
int f[N];
vector<int> pre[N]; void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> a[i];
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i)
{
for (int j = m; j >= a[i]; --j)
{
if (f[j] <= f[j - a[i]] + 1 && (f[j - a[i]] || j - a[i] == 0))
{
f[j] = f[j - a[i]] + 1;
pre[j] = pre[j - a[i]];
pre[j].push_back(a[i]);
}
}
}
if (f[m])
{
for (int i = 0; i < pre[m].size(); ++i)
cout << pre[m][i] << "\n "[i < pre[m].size() - 1];
}
else
cout << "No Solution" << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}
//dfs回溯
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define debug(x) cerr << #x << '=' << x << endl
#define all(x) (x).begin(), (x).end()
#define rson id << 1 | 1
#define lson id << 1
#define int long long
#define mpk make_pair
#define endl '\n'
using namespace std;
typedef unsigned long long ULL;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10, M = 4e5 + 10; int n, m;
int a[N];
bool vis[N];
vector<int> ans;
bool flag; void dfs(int idx, int sum)
{
if (sum > m)
return;
if (sum == m)
{
flag = true;
for (int i = 0; i < ans.size(); ++i)
cout << ans[i] << "\n "[i < ans.size() - 1];
return;
}
for (int i = idx; i <= n; ++i)
{
if (!vis[i])
{
vis[i] = true;
ans.push_back(a[i]);
dfs(i + 1, sum + a[i]);
ans.pop_back();
vis[i] = false;
if (flag)
return;
}
}
} void solve()
{
cin >> n >> m;
int sum = 0;
for (int i = 1; i <= n; ++i)
cin >> a[i], sum += a[i];
if (sum < m)
{
cout << "No Solution" << endl;
return;
}
sort(a + 1, a + n + 1);
dfs(1, 0);
if (!flag)
cout << "No Solution" << endl;
}
signed main(void)
{
Zeoy;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}

2023CCCC选拔赛的更多相关文章

  1. 2016中国大学生程序设计竞赛 - 网络选拔赛 C. Magic boy Bi Luo with his excited tree

    Magic boy Bi Luo with his excited tree Problem Description Bi Luo is a magic boy, he also has a migi ...

  2. 2016 ccpc 网络选拔赛 F. Robots

    Robots Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  3. Codevs 2296 仪仗队 2008年省队选拔赛山东

    2296 仪仗队 2008年省队选拔赛山东 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 题解 题目描述 Description 作为体育委员,C君负责这次运动 ...

  4. Codevs 2449 骑士精神 2005年省队选拔赛四川

    2449 骑士精神 2005年省队选拔赛四川 时间限制: 1 s 空间限制: 128000 KB 题目等级 : **大师 Master** 题目描述 Description 在一个5×5的棋盘上有12 ...

  5. JSU省赛队员选拔赛个人赛1(Coin Change、Fibbonacci Number、Max Num、单词数、无限的路、叠筐)

    JSU省赛队员选拔赛个人赛1 一.题目概述: A.Coin Change(暴力求解.动态规划)     B.Fibbonacci Number(递推求解) C.Max Num(排序.比较) D.单词数 ...

  6. 2013 CSU校队选拔赛(1) 部分题解

    A: Decimal Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 99   Solved: 10 [ Submit][ Status][ Web ...

  7. HDU 6447 - YJJ's Salesman - [树状数组优化DP][2018CCPC网络选拔赛第10题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447 Problem DescriptionYJJ is a salesman who has tra ...

  8. CSUST选拔赛题解

    本鶸鸡于本月10号参加了蔽校的选拔赛,成绩差的死,大部分的题都是赛后花了好长时间才补出来的,其中有些题还是靠QAQorz大佬帮忙才能解决,感谢Qls对我的帮助~接下来就附带上我的暴力题解,大佬们有更好 ...

  9. 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...

  10. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

随机推荐

  1. C# 调用WebService 笔记

    最近开发工作涉及到一些关于webService调用的问题,因为太久没有做过这部分,踩了一点坑,做个笔记记录一下,避免下次踩坑. 说明 C#调用webService基本有两种方法,一种是静态调用,也就是 ...

  2. C# – class, filed, property, const, readonly, get, set, init, required 使用基础

    前言 心血来潮,这篇讲点基础的东西. Field 比起 Property,Field 很不起眼,你若问 JavaScript,它甚至都没有 Field. 但在 C#,class 里头真正装 value ...

  3. 2024csps初赛记

    对于此次初赛,教训有不少,有一些差点把自己整死. 第一点,铅笔只能用2B,不要尝试使用HB 2nd:一定要带涂卡笔和橡皮,不然就算借别人用了也会发现橡皮还不如手擦的干净(可能因为这个原因我都要丢几分) ...

  4. 《Vue.js 设计与实现》读书笔记 - 第6章、原始值的响应式方案 & 响应式总结

    第6章.原始值的响应式方案 6.1 引入 ref 的概念 既然原始值无法使用 Proxy 我们就只能把原始值包裹起来. function ref(val) { const wrapper = { va ...

  5. Android Qcom USB Driver学习(十)

    本章主要是基于之前的学习,实现一个hidraw的驱动,发现有两种用于识别usb设备的方式,放别是usb_device_id和hid_device_id hid_probe (1)hid_device_ ...

  6. 4.3 等比数列及其前n项和

    \(\mathbf{{\large {\color{Red} {欢迎到学科网下载资料学习}} } }\)[[高分突破系列] 高二数学下学期同步知识点剖析精品讲义! \(\mathbf{{\large ...

  7. .Net 的扩展方法

    // 扩展方法 // ps:js中的扩展方法 比如 给数组定义一个自定义的全局的方法 使用 prototype (原型链) // .Net 给 string 添加一些扩展方法 String 是一个密封 ...

  8. Centos7下非lvm的分区扩容

    Centos7下非lvm的分区扩容(重要) 前言:一般在生产环境中,如果需要使用一个分区保存大量的文件,建议的做法是在虚拟化环境中增加一块单独的硬盘,挂载一个单独的分区,比如 /data 上图我们可以 ...

  9. 宏定义define的用法

    #define read(x) scanf("%d",&x); 这行代码是一个宏定义,使用了 C 语言中的 #define 指令.它的作用是定义一个名为 read 的宏,用 ...

  10. KubeKey 部署 K8s v1.28.8 实战

    在某些生产环境下,我们仅需要一个原生的 K8s 集群,无需部署 KubeSphere 这样的图形化管理控制台.在我们已有的技术栈里,已经习惯了利用 KubeKey 部署 KubeSphere 和 K8 ...