Codeforces Round 1040 (Div. 2) A - D題詳細題解

本文為Codeforces Round 1040 (Div. 2) A - D題的詳細題解, 覺得有幫助或者寫的不錯可以點個贊!

目錄

題目A:

題目大意:

解題思路:

代碼(C++):

題目B:

題目大意:

解題思路:

代碼(C++):

題目C:

題目大意:

解題思路:

代碼(C++):

題目D:

題目大意:

解題思路:

代碼(C++):


題目A:

Problem - A - Codeforces

題目大意:

現在定義,a是數組,sum(a)即為數組a中所有元素的和。

mex(a)即為數組a的最小排除數,也就是不在數組a中的最小非負整數

現在給出你一個數組S,并且剛開始你的得分為0。

每次操作你可以從數組中取出一個一部分元素(也就是原數組會少一部分元素),把這部分元素組成的數組設置成b。

你可以對你的分數加上sum(b)或者mex(b)。

在你進行任意次操作后,求出得分的最大值。

解題思路:

感性的分析,取出來的數字要使得mex值很大,那肯定要求很苛刻,要包含從0開始連續的數字才行。

理性的分析,

mex{0} > sum{0}

mex{0, 1} > sum{0, 1}

mex{0, 1,? 2} == sum{0, 1, 2}

mex{0, 1, 2, 3} < sum(0, 1, 2, 3)

很容易分析出,接下來的mex都是小于sum的

也就是得出結論,數組中有0和1的時候,取出0,1,并且把分數加上mex。

其他時候再加上sum。

更深層次的思考,mex{1} < sum{1}, mex{0} > sum{0}。

那么得出最終結論:

我們把數組中的每一個0單獨取出來,加上mex{0},也就是1,也就是0的個數。

然后把其他的數字取出來,直接加到分數上。

代碼(C++):

void solve() {int n;std::cin >> n;int sum = 0, cnt0 = 0;for (int i = 0; i < n; i++) {int x;std::cin >> x;//求出這些數字的總和sum += x;//0可以單獨拿出來作為一個集合{0},MEX{0} = 1//所以只需要求出1的數量即可if (x == 0) {cnt0++;}}std::cout << sum + cnt0 << "\n";
}

題目B:

Problem - B - Codeforces

題目大意:

現在給你一個數組,里面只包含元素0, 1, 2, 并且保證0,1,2的三個數字的數量至少為1。

現在玩家A,要從數組的第一個元素開始,走到最后一個元素,每次可以往左或者往右走一格。

每次經過的元素都會加在自己的得分上(每一個元素都可以重復的計算),玩家A的目標是在走到最后一個元素上并且加到那個元素的值后,得分恰好為S (不能超過也不能小于S)。

現在初始數組為a。

現在你是玩家B,你需要重新打亂數組,使得玩家A怎么都不能得到分數S。

輸出打亂后的數組,如果玩家A怎么都能得到分數S,輸出-1.

解題思路:

我們很容易注意到,玩家A直接從頭走到尾,會加上數組a的所有元素,我們記作tot。

也就是說,玩家A能獲得的分數最小值為tot,那么S < tot的時候,肯定是無法恰好獲得S分的,此時怎么排列數組都可以。

當S == tot的時候,一遍走過去就恰好達到分數S了,此時無論怎么排列數組,都會產生S分。

當S > tot的時候,此時玩家A就可以通過”刷分“操作來獲取更多的得分。

我們進行如下分析:

由于數組中只存在0, 1, 2。并且保證0,1,2的三個數字的數量至少為1。

當數組中有01相鄰的時候,“左右橫跳”,可以獲得任意的得分。

從上面的結論可以知道,在S? > tot的前提下,如果數組中有0,1相鄰,玩家A肯定能獲得恰好S分。

當數組中有02相鄰的時候,每次左右橫跳,都會獲得得分2。

當數組中有11相鄰的時候,每次左右橫跳,都會獲得得分3。

當數組中有12相鄰的時候,每次左右很跳,都會獲得得分4。

根據上述分析,我們現在把0和1分開擺放,可以類似于:

{0, 0, ..., 0, 2, 2, ..., 2, 1, ... ,1},現在S > tot。

我們再進行如下的分析:

當S ==?tot + 1,玩家A無論怎么操作都得不到S。

當S == tot + 2,玩家A可以通過02橫跳來得到。

當S == tot + 3,? 11橫跳。

當S == tot + 4,? 21橫跳。

...

也就是只有在S == tot + 1的時候,玩家A怎么操作都得不到S。

綜合上述推理我們即可實現代碼。

代碼(C++):

void solve() {int n, s;std::cin >> n >> s;//分別計算出0,1,2的數量int cnt0 = 0, cnt1 = 0, cnt2 = 0;for (int i = 0; i < n; i++) {int x;std::cin >> x;if (x == 0) {cnt0++;} else if (x == 1) {cnt1++;} else {cnt2++;}}//根據數組中1,2的數量計算數組元素的總和int tot = cnt1 + cnt2 * 2;/*此部分分析看題解*/if (s < tot || s == tot + 1) {for (int i = 0; i < cnt0; i++) {std::cout << "0 ";}for (int i = 0; i < cnt2; i++) {std::cout << "2 ";}for (int i = 0; i < cnt1; i++) {std::cout << "1 ";}std::cout << "\n";} else {std::cout << "-1\n";}
}

題目C:

Problem - C - Codeforces

題目大意:

現在有m個數對(ai, bi),我們定義集合S = {(a1, b1), (a2, b2), (a3, b3), ...,(am, bm)}。

現在定義兩個值f(S)和g(S)。

1.把每個數對中的(a,b)表示一個區間[a, b]。

f(S)為集合S所包含的所有區間的并集長度

2.現在(a, b)為圖中的一條無向邊。

g(S)是一個長度至少為3的環的節點數量。

現在給你n個數對(a, b),你需要從中取一部分數對組成集合S,你需要使得

f(S) - g(S)盡可能的大,輸出此時你取的集合大小和集合里面包含的元素(原來數對的索引)。

解題思路:

感性的思考,定義t = f(S) - g(S),要使得t越來越大,那么我們需要使得f(S)越大,g(S)越小。

取更多的數對只會讓f(S)越大,但是如果出現環的話,g(S)會瞬間增大很多。

也就是說,我們盡可能的取更多的數對,但是盡可能的不讓g(S)出現環,此時能讓t盡可能的最大。

理想分析:對于一些數對,[x1, x2], [x2, x3], [x3, x4]...[x(k - 1), x(k)],他們兩兩相連組成了一個環,也就是x1 == xk。

很容易知道這段區間的并集大小就是{x1, x2, ..., xk}中的最大值減去最小值, 因為兩兩相連,不用考慮空的部分。

我們如果刪去其中的一個點[x1, x2],那么環就不存在了, 但是很容易發現并集大小是不變的。

所以,我們可以無腦的刪除所有可以連成環的點,這樣就可以保證最終的值是最大的!

可以用并查集快速判斷是否成環。實際操作看具體代碼

代碼(C++):

//https://leetcode.cn/discuss/post/3583665/fen-xiang-gun-ti-dan-chang-yong-shu-ju-j-bvmv/
class UnionFind {std::vector<int> fa;std::vector<int> sz;
public:int cc;UnionFind(int n) : fa(n), sz(n, 1), cc(n) {std::iota(fa.begin(), fa.end(), 0);}int find(int x) {if (fa[x] != x) {fa[x] = find(fa[x]);}return fa[x];}bool is_same(int x, int y) {return find(x) == find(y);}bool merge(int from, int to) {int x = find(from), y = find(to);if (x == y) {return false;}fa[x] = y;sz[y] += sz[x];cc--;return true;}int get_size(int x) {return sz[find(x)];}
};void solve() {int n;std::cin >> n;std::vector<std::pair<int, int>> a(n);for (int i = 0; i < n; i++) {std::cin >> a[i].first >> a[i].second;}int mx = 2 * n;UnionFind uf(mx + 1);std::vector<int> ans;for (int i = 0; i < n; i++) {int u = a[i].first;int v = a[i].second;if (uf.merge(u, v)) {ans.push_back(i + 1);}}std::cout << ans.size() << "\n";for (int x : ans) {std::cout << x << " ";}std::cout << "\n";
}

題目D:

Problem - D - Codeforces

題目大意:

現在有一個長度為n的排列P。

你需要構造一個長度為n的數組a,對于每一個ai,

你可以選擇ai = pi 或者 ai = 2 * n - pi。

你的目的是使得數組a中的逆序對數目最少,輸出這個最小數目。

解題思路:施工中

代碼(C++):

//https://leetcode.cn/discuss/post/3583665/fen-xiang-gun-ti-dan-chang-yong-shu-ju-j-bvmv/
template<typename T>
class FenwickTree {std::vector<T> tree;public:FenwickTree(int n) : tree(n + 1, 0) {}void update(int i, T val) {for (; i < tree.size(); i += i & -i) {tree[i] += val;}}T pre(int i) const {T res = 0;for (; i > 0; i &= i - 1) {res += tree[i];}return res;}T query(int l, int r) const {if (r < l) {return 0;}return pre(r) - pre(l - 1);}T total(int n) const {return pre(n);}
};void solve() {int n;std::cin >> n;std::vector<int> p(n + 1);for (int i = 1; i <= n; i++) {std::cin >> p[i];}std::vector<int> l(n + 1), r(n + 1);FenwickTree<int> bit(n);i64 base = 0;for (int i = 1; i <= n; i++) {int x = i - 1 - bit.pre(p[i]);l[i] = x;base += x;bit.update(p[i], 1);}bit = FenwickTree<int> (n);for (int i = n; i >= 1; i--) {int x = bit.total(n) - bit.pre(p[i]);r[i] = x;bit.update(p[i], 1);}i64 ans = base;for (int i = 1; i <= n; ++i) {int x = r[i] - l[i];if (x < 0) {ans += x;}}std::cout << ans << '\n';
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91511.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91511.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91511.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構 之 【排序】(計數排序)

目錄 1.計數排序的思想 2.計數排序圖解 3.計數排序代碼邏輯 3.1求原數組最大最小值及計數數組的創建 3.2計數 3.3覆蓋寫 3.4釋放資源 4.計數排序的注意事項 5.計數排序的時間復雜度與空間復雜度 以升序為例 1.計數排序的思想 前面我們學習的快排、歸并排序、希爾排序.…

Ascend CANN/ACL API 模型部署加速最佳實踐

1. 模型輸入相關問題 圖像尺寸信息 模型輸入尺寸由原始模型決定,在轉換時固定 圖像尺寸信息是模型固有屬性,不是轉換時添加的 對于使用動態尺寸,可以在推理時自動根據當前的輸入尺寸推導輸出尺寸。 輸入格式(NCHW/NHWC) --input_format 不同框架默認格式不同: Caffe: 支持…

QT信號和槽怎么傳輸自己定義的數據結構

在 Qt 中&#xff0c;信號&#xff08;Signal&#xff09;和槽&#xff08;Slot&#xff09;機制默認支持許多內置類型&#xff08;如 int、QString、QList 等&#xff09;&#xff0c;但如果要傳輸 自定義數據結構&#xff08;如結構體、類對象&#xff09;&#xff0c;需要額…

借助于llm將pdf轉化為md文本

pdf轉化為md格式后&#xff0c;意味著非結構化文本轉為結構化文本&#xff0c;能清晰定位大標題、子標題&#xff0c;圖表。 方便后續處理&#xff0c;因為llamaindex和langchain能更有效切分md類文本&#xff0c;避免信息丟失。 1&#xff09;讀取pdf為txt 讀取pdf&#xf…

設計模式:中介者模式 Mediator

目錄前言問題解決方案結構代碼前言 中介者是一種行為設計模式&#xff0c;能讓你減少對象之間混亂無序的依賴關系。該模式會限制對象之間的直接交互&#xff0c;迫使它們通過一個中介者對象進行合作。 問題 假如你有一個創建和修改客戶資料的對話框&#xff0c; 它由各種控件…

計算機基礎速通--數據結構·線性表應用

如有問題大概率是我的理解比較片面&#xff0c;歡迎評論區或者私信指正。 考察線性表&#xff0c;核心圍繞其存儲結構特性、核心操作實現、場景應用選型三大維度&#xff0c;重點檢驗對基礎概念的理解、代碼實現能力及問題分析能力&#xff0c;通常會結合算法設計、復雜度分析和…

LeetCode Hot 100:42. 接雨水

題目 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖&#xff0c;計算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 解析 和題目 盛水最多的容器 類似&#xff0c; LeetCode Hot 100&#xff1a;11. 盛最多水的容器-CSDN博客 只是這里將每一個柱子視為一個寬度為…

【C語言入門級教學】字符指針變量

文章目錄1.字符指針變量2. 數組指針變量2.1 數組指針變量初始化3.?維數組傳參的本質1.字符指針變量 在指針的類型中我們知道有?種指針類型為字符指針 char* ; ?般使?: int main() { char ch w; char* pc &ch;//pc的類型是char**pcw;//對pc解引用 修改ch存放的內容…

【Shell腳本自動化編寫——報警郵件,檢查磁盤,web服務檢測】

Shell腳本自動化編寫Shell腳本自動化編寫一、判斷當前磁盤剩余空間是否有20G&#xff0c;如果小于20G&#xff0c;則將報警郵件發送給管理員&#xff0c;每天檢查一次磁盤剩余空間。第一步&#xff1a;準備工作第二步&#xff1a;配置郵件信息第三步&#xff1a;檢查磁盤的自動…

Java 接口(下)

三、接口的繼承性【基礎重點】 1. Java中的接口之間的繼承關系是多繼承&#xff0c;一個接口可以有多個父接口(1) 語法&#xff1a;interface 接口名 extends 父接口1,父接口2{} 2. 類和接口之間是多實現的關系&#xff1a;一個類可以同時實現多個接口(1) 語法&#xff1a;clas…

學習游戲制作記錄(各種水晶能力以及多晶體)8.1

1.實現創建水晶并且能與水晶進行交換位置的能力創建好水晶的預制體&#xff0c;添加動畫控制器&#xff0c;傳入待機和爆炸的動畫創建Crystal_Skill_Control腳本&#xff1a;掛載在水晶預制體上private float crystalExstTime;//水晶存在時間public void SetupCrystal(float _c…

在vscode 如何運行a.nut 程序(Squirrel語言)

在 VS Code 中運行 Squirrel 語言編寫的 .nut 程序&#xff0c;需要先配置 Squirrel 運行環境并安裝相關插件&#xff0c;具體步驟如下&#xff1a; 一、安裝 Squirrel 解釋器 Squirrel 程序需要通過其官方解釋器 squirrel 或 sq 執行&#xff0c;首先需要安裝解釋器&#xf…

【數據結構】生活中的數據結構:從吃飯與編程看棧與隊列思維

生活中的數據結構&#xff1a;從吃飯與編程看棧與隊列思維 在軟件開發的世界里&#xff0c;棧&#xff08;Stack&#xff09;和隊列&#xff08;Queue&#xff09;是兩種基礎的數據結構&#xff0c;它們以不同的順序管理數據&#xff1a;棧遵循后進先出&#xff08;LIFO&#x…

牛客——接頭密匙

題目鏈接&#xff1a;牛客--接頭密匙 該題是一個很顯然的前綴樹問題&#xff0c;只需要構建a中所有數組對應的前綴樹&#xff0c;之后求b所處前綴個數即可。關于前綴樹的構建&#xff0c;可以觀看左老師算法講解045的視頻&#xff0c;簡單來講就是用特殊字符將實際數據隔開&…

【Linux基礎知識系列】第六十三篇 - 文件編輯器基礎:vim

在 Linux 系統中&#xff0c;文本編輯器是系統管理員和開發人員不可或缺的工具。vim 是一個功能強大的文本編輯器&#xff0c;廣泛應用于 Linux 系統中。它支持多種編輯模式&#xff0c;提供了豐富的文本編輯功能&#xff0c;適用于編寫代碼、配置文件和文檔。掌握 vim 的基本使…

音頻驅動的視覺特效:粒子、動畫與Shader的融合技術

音頻驅動視覺效果的實現與應用1. 引言在互動媒體、游戲和數字藝術領域&#xff0c;音頻數據實時控制視覺元素已成為核心技術&#xff0c;它能創造沉浸式體驗&#xff0c;增強用戶參與感。例如&#xff0c;音樂會可視化或VR游戲中&#xff0c;音頻信號驅動粒子流動、動畫變化和S…

機器學習環境配置

【終極指南】吃透機器學習環境配置&#xff1a;從Conda、CUDA到Docker容器化 大家好&#xff01;在機器學習的旅程中&#xff0c;一個穩定、可復現的環境是成功的基石。 第一部分&#xff1a;核心理念——為何環境配置如此重要&#xff1f; 任何機器學習模型的運行&#xff0c;…

【14】大恒相機SDK C#開發 ——Bitmap.UnlockBits()什么意思?有什么用?bmpData.Scan0;什么意思?有什么用?

文章目錄1 Bitmap.UnlockBits()2 bmpData.Scan01 Bitmap.UnlockBits() 在 C# 中&#xff0c;Bitmap.UnlockBits() 方法的作用是解鎖通過 Bitmap.LockBits() 方法鎖定的位圖數據&#xff0c;并釋放相關的位圖數據結構。 當你使用 Bitmap.LockBits() 方法鎖定位圖數據時&#x…

什么是doris

文章目錄簡介使用場景Apache Doris 主要應用于以下場景&#xff1a;實時數據分析&#xff1a;湖倉融合分析&#xff1a;半結構化數據分析&#xff1a;Apache Doris 的核心特性詳細請看官方文檔&#xff1a; Apache Doris介紹簡介 Apache Doris 是一款基于 MPP 架構的高性能、實…

python+pyside6的簡易畫板

十分簡單的一個畫板程序&#xff0c;用QLabel控件作為畫布&#xff0c;在畫布上可以畫出直線、矩形、填充矩形、園&#xff0c;橢園、隨手畫、文本等內容。將原先發布的畫板程序中的畫文本方法修改成了原位創建一編輯框&#xff0c;編輯框失去焦點后&#xff0c;即將文本畫在畫…