Codeforces Round 787 (Div. 3)(A,B,C,D,E,F,G)

Codeforces Round 787 (Div. 3) - Codeforces

A. Food for Animals

題意

有a袋狗糧,b袋貓糧,c袋通用糧食,問現在有x只狗y只貓,每一個動物都要吃一袋糧食,問糧食夠不夠吃

思路

首先肯定考慮貓吃貓糧,狗吃狗糧。然后再考慮如果不夠吃的話才會去吃通用糧食

代碼

#include<bits/stdc++.h>
using namespace std;
void solve(){int a,b,c,x,y;cin>>a>>b>>c>>x>>y;x-=a;y-=b;if(x>0)c-=x;if(y>0)c-=y;if(c>=0){cout<<"YES\n";return;}cout<<"NO\n";
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;cin>>T__;while(T__--)solve();return 0;
}

B. Make It Increasing

題意

給定一個序列,問需要多少次操作才能使得整個序列嚴格單調遞增

每次操作可以將a[i]變成a[i]/2(下取整)

思路

貪心,因為元素不能變大,所以我們肯定對最后一個元素不進行操作最優,對倒數第二個元素必須操作成比最后一個元素小,倒數第三個元素必須操作成比倒數二個元素小…依次類推就可以求解出最后的操作次數,注意,如果后一個數字已經是0,則說明無論當前數怎么操作都不能變小,所以輸出-1

代碼

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){int n;cin>>n;vector<int>a(n+1,0);for(int i=1;i<=n;i++)cin>>a[i];int res=0;for(int i=n-1;i>=1;i--){if(a[i+1]==0){cout<<-1<<"\n";return;}while(a[i]>=a[i+1])a[i]/=2,res++;}cout<<res<<"\n";
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;cin>>T__;while(T__--)solve();return 0;
}

C. Detective Task

題意

有n個人先后進入房間,等第n個人結束以后發現原本在墻上的畫不見了,現在詢問n個人進門是否看到了畫,每個人的答案在yes,no,不記得三種情況之一(保證沒有偷畫的人一定說的是真話,偷畫的人答案可以任意),問有多少人有可能偷畫

思路

思考一下我們發現,實際上不記得這種情況的線索對于我們來說是不能直接確定答案的,如果對于一個人來說在他前面的人說yes或者?并且在他后面的人說no或者?則說明這個人有可能偷畫,我們只需要從前往后標記前綴yes直到出現no停止標記,從后往前標記no直到出現yes停止標記即可

代碼

/*
是否為小偷?
假設當前這個人是小偷,那么在他之前/之后的所有操作都是合法的,即在之前只能是1或者?,在其之后只能是0或者?
從前往后標記是否出現0,從后往前標記是否出現1
*/
#include<bits/stdc++.h>
using namespace std;
void solve(){string s;cin>>s;int n=s.size();s=" "+s;vector<int>vis1(n+2,0),vis2(n+2,0);int fla1=0,fla2=0;for(int i=1;i<=n;i++){if(s[i]=='0')fla1=1;vis1[i]=fla1;}for(int i=n;i>=1;i--){if(s[i]=='1')fla2=1;vis2[i]=fla2;}int cnt=0;for(int i=1;i<=n;i++){if(vis1[i-1]+vis2[i+1]==0)cnt++;}cout<<cnt<<'\n';
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;cin>>T__;while(T__--)solve();return 0;
}

D. Vertical Paths

題意

給定一棵樹問至少能分成幾條不重復的鏈(鏈中相鄰兩個元素滿足是父子關系)

思路

我們發現無論如何對于葉子節點來說,是一定要產生一條新的鏈的,所以鏈的最小條數就是葉子節點的個數。至于如何輸出,我們只需要找到葉子節點后從葉子節點往上一直走直到走到被標記過的點(說明這個點已經被其他鏈占有)停止。簡單模擬一下即可

代碼

/*
葉子節點有幾個就說明要拆為幾條路徑
我們考慮從葉子節點往上摘鏈*/
#include<bits/stdc++.h>
using namespace std;
// #define int long long
const int mxn=1e6+5;
vector<vector<int>>res;
vector<int>edge[mxn];
int rt;
int vis[mxn];
vector<int>leaf;
void dfs(int u,int fa){int fla=0;for(auto v:edge[u]){if(v==fa)continue;dfs(v,u);fla=1;}if(!fla)leaf.push_back(u);
}
void solve(){int n;cin>>n;res.clear(),leaf.clear();for(int i=1;i<=n;i++)edge[i].clear(),vis[i]=0;vector<int>fa(n+1,0);for(int i=1;i<=n;i++){cin>>fa[i];if(i==fa[i]){rt=fa[i];fa[i]=-1;continue;}else{edge[fa[i]].push_back(i);edge[i].push_back(fa[i]);}}dfs(rt,0);for(auto lef:leaf){int now=lef;vector<int>kk;while(now!=-1&&vis[now]==0){vis[now]=1;kk.push_back(now);now=fa[now];}if(kk.size()){reverse(kk.begin(),kk.end());res.push_back(kk);}}cout<<res.size()<<"\n";for(auto v:res){cout<<v.size()<<"\n";for(auto x:v){cout<<x<<" ";}cout<<"\n";}cout<<"\n";}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;cin>>T__;while(T__--)solve();return 0;
}

E. Replace With the Previous, Minimize

題意

給定一個字符串,每次操作可以操作一種字母x使得字符串中所有的x都變成x-1(b變成a,c變成b,d變成c…),最多能進行k次操作,問怎么樣才能使得最后得到的字符串字典序最小

思路

首先我們考慮k很大的時候,如果k>=25,說明一定可以從z變成y,y變成x…c變成b,b變成a的操作使得所有字符都變成a,那么這一定是字典序最小的時候

再考慮k小的時候我們怎么處理。首先肯定考慮優先把第一個字符變成a,然后再考慮第二個字符能不能變成a…直到最后操作次數用完,那么我們會發現一個問題,我們要保證在第一個字母能變成a的基礎上還要保持有盡可能多的前面的數字變小,我們實際上可以先把大于s[1]的字母Px(Px是我們假定的一個字母)盡可能變成s[1]然后再一起從s[1]變成a,那么我們只需要讓Px盡可能大即可,找到Px值以后我們就可以直接模擬從Px到a的過程即可。因為有可能會出現k能滿足從前i個字母變成a但不滿足從s[i+1]到a,且k在操作完以后還有剩余,所有我們優先把s[i+1]盡可能往小的方向調整即可。

代碼

/*
如果K(K>=25)很大,則一定可以變成aaaaa
*/
#include<bits/stdc++.h>
using namespace std;
// #define int long long
void solve(){int n,k;cin>>n>>k;string s;cin>>s;s=" "+s;if(k>=25){for(int i=1;i<=n;i++){cout<<"a";}cout<<'\n';return;}//否則的話K很小,那么就可以直接模擬了//先考慮第一位變到a需要多少步,再考慮第二位變成第一位需要多少步,再考慮第三位變成第二位需要多少步....//直到這個數值>kint r=0;int ma=0;for(int i=1;i<=n;i++){if(s[i]-'a'<=k)r=i,ma=max(ma,s[i]-'a');else break;}k-=ma;for(int i=1;i<=n;i++){if(s[i]<=char('a'+ma))s[i]='a';}if(r+1<=n){for(int tt=1;tt<=k;tt++){char tmp=s[r+1];for(int i=1;i<=n;i++){if(s[i]==tmp)s[i]=char(s[i]-1);}//cout<<s<<"\n";}}for(int i=1;i<=n;i++)cout<<s[i];cout<<"\n";
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;cin>>T__;while(T__--)solve();return 0;
}

F. Vlad and Unfinished Business

題意

給定起點和終點,問從起點到終點必須經過點a[1]…a[k]的最短路

思路

一開始以為這道題是無向圖,但又看了一眼數據范圍2e5覺得完全無從下手,然后再看了一眼題目發現給定的是一棵樹,那么這道題就變得有說法了

首先因為沒有對根節點的要求,我們為了方便可以將起點作為根節點,那么我們實際上就是要從起點經過若干個特定點最后再到終點,然后我們發現一個很有意思的現象,我們把從起點到終點的簡單路徑稱為主干,那么只要這個目標節點不在主干上,我們就需要從主干上的某個節點x出發去訪問這個節點的子樹然后再走回x,相當于在非主干的路上我們必須每條路徑都走兩次,結合樹形DP的一些思路,尋思著要維護一些什么方便我們求最后的答案。我們發現最后要求的答案實際上就是從起點走到若干個目標點(包括終點)再回到起點的路程-從起點走到終點的路程。那么問題就容易解決了,我們維護每顆子樹下是否存在目標節點,如果存在目標節點,就說明從當前節點到其兒子節點的這條路徑是必須要走的并且是要走兩次的(來回)并且還需要加上從子樹內部到這個目標點所需要走的距離(即這棵子樹中往下要走至少多少路程到達目標節點后再回到這個子樹的根節點)至于如何求解這些信息,我們只需要從葉子節點往上更新信息直到最后在根節點處停止。最后只需要在根節點(起點)統計我們需要的這個值然后再減去終點的深度(即起點到終點的最短路徑)即為答案

代碼

/*
給定起點和終點,問從起點到終點必須經過a[1]....a[k]的最短路
經過從起點走到目標點再回到起點的最短路
把中點也算作一個目標頂點,
那么最好的答案就是從起點走到目標點再回到起點的最短路-從起點到終點的最短路
*/
#include<bits/stdc++.h>
using namespace std;
const int mxn=1e6+5;
vector<int>edge[mxn];
int vis[mxn];
int ans[mxn];
int dep[mxn];
void dfs(int u,int fa){for(auto v:edge[u]){if(v==fa)continue;dep[v]=dep[u]+1;dfs(v,u);vis[u]=max(vis[v],vis[u]);if(vis[v])ans[u]+=2+ans[v];}
}
void solve(){int n,k;cin>>n>>k;int st,ed;cin>>st>>ed;for(int i=1;i<=n;i++)edge[i].clear(),vis[i]=0,dep[i]=0,ans[i]=0;for(int i=1;i<=k;i++){int x;cin>>x;vis[x]=1;}vis[ed]=1;for(int i=1;i<n;i++){int u,v;cin>>u>>v;edge[u].push_back(v);edge[v].push_back(u);}dfs(st,0);cout<<ans[st]-dep[ed]<<"\n";
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;cin>>T__;while(T__--)solve();return 0;
}

G. Sorting Pancakes

題意

給定一個長度為n的序列,每個位置上都有a[i]個餡餅,每次可以選擇相鄰兩個元素一個減1一個加1,問經過至少多少次操作能使得序列非遞增

思路

我們可以考慮統一方向,只考慮位置i和i+1兩個元素,每次操作實際上就是從i盤中取(正數)個餡餅放入i+1盤,或者從i盤取(負數)個餡餅放入i+1盤(等價于從右邊往左放整數個餡餅)

考慮到沒有貪心策略,而且n的范圍很小,故我們想到可以采用DP,我們需要維護的狀態有:已經考慮了多少個盤子,在這之前的盤子總共裝了多少個,當前盤子裝了多少個,故我們需要用三維DP

定義dp[i][j][k]dp[i][j][k]dp[i][j][k]:表示前i個盤子中,總共放了j個餡餅,且當前第i個盤子放了k個餡餅(并且保證前i個盤子已經構成了非遞增的序列)

那么我們如何考慮相鄰兩個盤子的交換操作過程呢?

前i盤子中只有盤i是靈活的,因為只要前i-1個盤子總數固定,第i-1個盤子數量固定,那么前i-1個盤子就是不可再動的了。唯一可以調節的就是第i個盤子里面的個數,調節盤子之間餡餅的個數是有代價的,且必須經過 i+1(因為前i-1個盤子已經固定,i只能和i+1交換)

假設前i個盤子有j個餡餅且當前第i個盤子有k個餡餅,那么他可以從前i-1個盤子有j-k個餡餅且當前第i-1個盤子有w個餡餅轉移得到(k<=w<=j-k),但因為原來的前i個盤子中有S[i]個餡餅,但當前總共只有j個餡餅,所以還要從i+1交換∣s[i]?j∣|s[i]-j|s[i]?j次操作使得當前前i個盤子總共只有j個餡餅(實際上在轉移過程中只會因為調節總數j和實際S[i]不一致而產生代價)

即轉移方程為dp[i][j][k]=min?w=kmdp[i?1][j?k][w]+∣j?S[i]∣dp[i][j][k] = \min_{w=k}^{m} dp[i-1][j-k][w] + |j - S[i]|dp[i][j][k]=minw=km?dp[i?1][j?k][w]+j?S[i]

但這樣做的復雜度會超時,因為需要枚舉i,j,k,w,復雜度為O(nm3)O(nm^{3})O(nm3)

我們發現因為只會在i和i-1層之間轉移,那么我們可以用滾動數組滾掉第一維i,那么我們僅僅需要維護min?w=kmdp[j?k][w]\min_{w=k}^{m} dp[j-k][w]minw=km?dp[j?k][w]即可,所以我們只需要單獨開一個數組維護后綴最小值即可

代碼

#include<bits/stdc++.h>
using namespace std;
#define int long long
int mi[405][405];
int dp[405][405];
int s[405];//前綴和
void solve(){int n,m;cin>>n>>m;for(int i=1;i<=n;i++)cin>>s[i],s[i]+=s[i-1];for(int i=0;i<=m;i++)dp[0][i]=1;for(int i=1;i<=n;i++){//當前在處理第i層,那么mi維護的就是第i-1層的信息//具體的,mi[j-k][k]表示w=k~m的最小dp[i-1][j-k][w]for(int j=0;j<=m;j++){//前i個盤子總共餡餅數量for(int k=0;k<=j;k++){//第i個盤子的餡餅數量//dp[i][j][k]=min(dp[i-1][j-k][w])+|j-s[i]| (k<=w<=m)dp[j][k]=mi[j-k][k]+abs(s[i]-j);}}memset(mi,0x3f,sizeof mi);//清空第i-1層的信息,準備維護第i層的信息for(int j=0;j<=m;j++){for(int k=j;k>=0;k--)mi[j][k]=min(mi[j][k+1],dp[j][k]);//維護后綴最小值}}int ans=0x3f3f3f3f3f3f3f3f;for(int i=0;i<=m;i++) ans=min(ans,dp[m][i]);//最后一個盤子的數量是不確定的,我們要從中枚舉挑選最小cout<<ans<<"\n";
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T__=1;//cin>>T__;while(T__--)solve();return 0;
}

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

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

相關文章

LLaMA-Factory的webui快速入門

一、webui的啟動方式 LLaMA-Factory 支持通過 WebUI 零代碼微調大語言模型。 在完成安裝 后&#xff0c;您可以通過以下指令進入 WebUI: llamafactory-cli webui 使用上面命令啟動服務后&#xff0c;即可使用默認7860端口進行訪問。訪問地址&#xff1a;http://ip:7860,截止…

【第四節】ubuntu server安裝docker

首先更新軟件源 sudo apt update sudo apt upgrade安裝docker 下載 Docker 官方 GPG 密鑰 # 1. 下載 Docker 官方 GPG 密鑰 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg再次更新軟件源…

Kubernetes的微服務

用控制器來完成集群的工作負載&#xff0c;那么應用如何暴漏出去&#xff1f;需要通過微服務暴漏出去后才能被訪問Service是一組提供相同服務的Pod對外開放的接口。借助Service&#xff0c;應用可以實現服務發現和負載均衡。service默認只支持4層負載均衡能力&#xff0c;沒有7…

退出登錄后頭像還在?這個緩存問題坑過多少前端!

目錄 1. 為什么退出登錄后頭像還在&#xff1f; ① 緩存沒清理干凈 ② 頭像URL沒更新 ③ 后端會話失效&#xff0c;但靜態資源可訪問 2. 怎么解決&#xff1f;5種常見方案 ? 方案1&#xff1a;強制刷新頁面&#xff08;簡單粗暴&#xff09; ? 方案2&#xff1a;給頭像…

Windows下白嫖ClaudeCode

我的邀請鏈接&#xff1a;https://anyrouter.top/register?afffMJn 我的邀請鏈接&#xff1a;https://anyrouter.top/register?afffMJn 我的邀請鏈接&#xff1a;https://anyrouter.top/register?afffMJn 兄弟們&#xff0c;交個朋友啊&#xff01;一定要用我的呀&#xff0…

windows在anaconda中下載安裝fasttext

windows在anaconda中下載安裝fasttext 1.訪問fasttext-wheel&#xff0c;點擊對應鏈接&#xff0c;下載對應Python版本、操作系統類型 的.whl文件&#xff1a; 鏈接地址&#xff1a;https://pypi.org/project/fasttext-wheel/#files 打開anaconda終端&#xff0c;切換到上面的…

mysql5.7系列-索引下推(cover_index)

什么是索引下推 ICP&#xff08;Index Condition Pushdown&#xff09;是在MySQL 5.6版本上推出的查詢優化策略&#xff0c;把本來由Server層做的索引條件檢查下推給存儲引擎層來做&#xff0c;以降低回表和訪問存儲引擎的次數&#xff0c;提高查詢效率。 回顧下mysql的架構分…

計算機網絡(基礎概念)

計算機網絡&#xff08;基礎概念&#xff09;1 初識協議1.1 協議分層2 OSI七層模型2.1 物理層2.2 數據鏈路層2.3 網絡層2.4 傳輸層2.5 應用層3 TCP/IP協議族3.1 什么是TCP/IP協議?3.1.1 OS與網絡關系4 網絡傳輸的基本流程4.1 局域網4.2 MAC地址5 跨網絡傳輸5.1 IP地址6 Socket…

專題 JavaScript 函數基礎

你將知道&#xff1a;函數聲明和表達式函數聲明和表達式之間的區別什么是匿名函數什么是 IIFE命名函數表達式this 關鍵字函數是調用該函數時執行的代碼塊 。函數聲明和表達式讓我們回顧一下它的語法&#xff1a;functionfunctionName(param1, param2, ..., paramN) {// Functio…

數據結構——優先隊列(priority_queue)的巧妙運用

優先隊列是一種相對高級的數據結構&#xff0c;它的底層原理是二叉堆。然而本篇不會執著于深挖其背后的原理&#xff0c;更主要的是理一下它在題目中的一些實用方法&#xff0c;幫助你更快的上手使用。 優先隊列(priority_queue) 優先隊列的特別之處就在于它可以自動進行排序&…

Java:繼承和多態(必會知識點整理)

主要內容繼承多態向上轉型向下轉型方法重寫方法重載super關鍵字動態綁定封裝訪問控制構造方法規則一、繼承 1. 概念&#xff1a; 一句話說就是&#xff1a;“共性抽取&#xff0c;代碼復用”子類會將父類中的成員變量或者成員方法繼承到子類中子類繼承父類之后&#xff0c;必須…

基于esp32系列的開源無線dap-link項目使用介紹

基于esp32系列的開源無線dap-link項目使用介紹&#x1f516;有關esp32/8266相關項目&#xff1a;需要自己搭建編譯環境&#xff1a; https://github.com/windowsair/wireless-esp8266-dap/tree/master&#x1f33f;支持esp32/c3/s3,支持在線固件燒錄&#xff0c;支持AP配網&…

深入了解linux系統—— 進程信號的產生

前言 進程在收到信號之后&#xff0c;可以立即處理&#xff0c;也可以在合適的時間再處理&#xff08;1-31號普通信號可以不被立即處理&#xff09; 信號不是被立即處理&#xff0c;信號就要被保存下來&#xff0c;讓進程在合適的時間再去處理。 相關概念 在了解進程是如何保存…

【Bluedroid】藍牙協議棧enable流程深度解析

本文詳細剖析 Bluedroid 藍牙功能啟用的核心流程&#xff0c;從enable()函數觸發開始&#xff0c;深入解析藍牙協議棧的異步啟動機制、核心協議模塊初始化、硬件控制器綁定及狀態同步全流程。重點闡述接口就緒性檢查、異步線程管理、配置文件回調機制等關鍵環節&#xff0c;揭示…

各種開發語言主要語法對比

各類主流編程語言的語法有著顯著差異&#xff0c;這些差異源于語言設計哲學&#xff08;簡潔性 vs 顯式性&#xff09;、應用領域&#xff08;系統級、Web、數據科學&#xff09;、運行方式&#xff08;編譯 vs 解釋&#xff09;以及支持的范式&#xff08;面向對象、函數式、過…

小鵬汽車6月交付車輛34,611輛,同比增長224%

小鵬汽車-W(09868)發布公告&#xff0c;2025年6月&#xff0c;小鵬汽車共交付智能電動汽車34,611輛&#xff0c;同比增長224%&#xff0c;這標志著小鵬汽車已連續第八個月交付量超過了30,000輛。2025年第二季度&#xff0c;小鵬汽車共交付103,181 輛智能電動車&#xff0c;創下…

深入理解觀察者模式:構建松耦合的交互系統

在軟件開發中&#xff0c;我們經常遇到這樣的場景&#xff1a;一個對象的狀態變化需要通知其他多個對象&#xff0c;并且這些對象需要根據變化做出相應的反應。比如&#xff0c;用戶界面中的數據變化需要實時反映到多個圖表上&#xff0c;或者電商系統中的庫存變化需要通知訂單…

React強大且靈活hooks庫——ahooks入門實踐之常用場景hook

什么是 ahooks&#xff1f; ahooks 是一個 React Hooks 庫&#xff0c;提供了大量實用的自定義 hooks&#xff0c;幫助開發者更高效地構建 React 應用。其中場景類 hooks 是 ahooks 的一個重要分類&#xff0c;專門針對特定業務場景提供解決方案。 安裝 ahooks npm install …

Qt常用控件之QWidget(一)

Qt常用控件之QWidget&#xff08;一&#xff09;1.QWidget2.enabled屬性2.geometry&#x1f31f;&#x1f31f;hello&#xff0c;各位讀者大大們你們好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列專欄&#xff1a;【Qt的學習】 &#x1f4dd;&#x1f4dd;本…

AIOT開發選型:行空板 K10 與 M10 適用場景與選型深度解析

前言 隨著人工智能和物聯網技術的飛速發展&#xff0c;越來越多的開發者、學生和愛好者投身于創意項目的構建。 在眾多的開發板中&#xff0c;行空板 K10 和 M10 以其獨特的優勢脫穎而出。 本文旨在為讀者提供一份詳盡的行空板 K10 和 M10 對比分析&#xff0c;從適用場景、…