feat: 添加YACS竞赛题目解答和启用地址消毒选项

添加四个YACS竞赛题目解答文件(yacs1135.cpp, yacs1145.cpp, yacs1146.cpp, yacs1147.cpp)
在CMakeLists中启用地址消毒选项以帮助调试
This commit is contained in:
Zengtudor 2025-11-16 17:39:49 +08:00
parent a288f0c5ec
commit 1b4eec97e6
5 changed files with 167 additions and 2 deletions

View File

@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.15)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_compile_options(-Wall)
# add_compile_options(-fsanitize=address,pointer-compare,pointer-subtract,undefined -fno-omit-frame-pointer)
# add_link_options(-fsanitize=address,pointer-compare,pointer-subtract,undefined -fno-omit-frame-pointer)
add_compile_options(-fsanitize=address,pointer-compare,pointer-subtract,undefined -fno-omit-frame-pointer)
add_link_options(-fsanitize=address,pointer-compare,pointer-subtract,undefined -fno-omit-frame-pointer)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
set(CMAKE_CXX_STANDARD 26)

28
src/11/16/yacs1135.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <cstdint>
#include <iostream>
#include <istream>
using ll = int64_t;
const ll maxn=1e6+7;
ll a[maxn],ans;
int main(){
ll n;
std::cin>>n;
for(ll i=1;i<=n;i++){
std::cin>>a[i];
}
ll l=1,r=n;
while(l<r){
if(a[l]<a[r]){
a[l+1]+=a[l];
ans++;
l++;
}else if(a[l]>a[r]){
a[r-1]+=a[r];
ans++;
r--;
}else{
l++,r--;
}
}
std::cout<<ans<<"\n";
}

23
src/11/16/yacs1145.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
using ll = int64_t;
ll a[3];
static inline ll check(ll n){
if(n<0)return false;
for(ll i=0;i<3;i++){
if(a[i]<n+i)return 0;
}
return n*3+3;
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
for(int i=0;i<3;i++)std::cin>>a[i];
std::cout<<std::max({check(a[0]),check(a[1]-1),check(a[2]-2)})<<"\n";
}

23
src/11/16/yacs1146.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
using ll = int64_t;
ll n,nmax,ans;
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n;
for(ll i=1;i<=n;i++){
ll tmp;
std::cin>>tmp;
nmax=std::max(nmax,tmp);
if(nmax<=i){
ans++;
}
}
std::cout<<ans<<"\n";
}

91
src/11/16/yacs1147.cpp Normal file
View File

@ -0,0 +1,91 @@
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
struct Node {
int val, idx;
Node *left, *right;
Node(int v, int i) : val(v), idx(i), left(nullptr), right(nullptr) {}
};
int main() {
int n, k;
cin >> n >> k;
vector<int> a(n + 1);
vector<Node*> nodes(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
nodes[i] = new Node(a[i], i);
}
// 建立双向链表
for (int i = 1; i <= n; i++) {
if (i > 1) nodes[i]->left = nodes[i - 1];
if (i < n) nodes[i]->right = nodes[i + 1];
}
// 最大堆,按值排序
auto cmp = [](Node* x, Node* y) { return x->val < y->val; };
priority_queue<Node*, vector<Node*>, decltype(cmp)> pq(cmp);
for (int i = 1; i <= n; i++) {
pq.push(nodes[i]);
}
vector<int> team(n + 1, 0); // 0 未分配
int ct = 1; // 当前队伍
while (!pq.empty()) {
Node* cur = pq.top();
pq.pop();
if (team[cur->idx] != 0) continue; // 已分配
// 标记当前节点
vector<Node*> tr;
tr.push_back(cur);
// 向左扩展 k 个
Node* l = cur->left;
for (int i = 0; i < k && l != nullptr; i++) {
tr.push_back(l);
l = l->left;
}
// 向右扩展 k 个
Node* r = cur->right;
for (int i = 0; i < k && r != nullptr; i++) {
tr.push_back(r);
r = r->right;
}
// 标记这些节点
for (Node* node : tr) {
if (team[node->idx] == 0) {
team[node->idx] = ct;
}
}
// 从链表中删除这些节点
// 找到删除区间的最左和最右节点
Node* lb = tr.back()->left;
Node* rb = tr.back()->right;
for (Node* node : tr) {
if (node->left) lb = node->left;
if (node->right) rb = node->right;
}
if (lb) lb->right = rb;
if (rb) rb->left = lb;
// 切换队伍
ct = 3 - ct; // 1 -> 2, 2 -> 1
}
for (int i = 1; i <= n; i++) {
cout << team[i];
if (i < n) cout << " ";
}
cout << "\n";
}