蓝桥杯C++大学B组一个月冲刺记录2024/3/23
规则:每日三题
人是真的菜啊
倍增lca的板子完全忘记了,明天再学一遍再补吧
1.拜访棋子
给定一个 1×n 的方格棋盘。其中,一些方格上没有棋子(用 0 表示),一些方格上放有棋子(用 1表示)。
现在,你可以挑选棋盘中不超过 k 个空方格,在其中放上棋子。
我们的目标是让棋盘中最长的连续相邻棋子段的长度尽可能大。连续相邻棋子段:一段棋子连续相邻的排列在一起,中间没有空方格将它们隔开。
输出最长连续相邻棋子段的最大可能长度以及最终的棋盘盘面。
前缀和 + 双指针
#include<iostream>
using namespace std;
const int N = 3e5 + 10;
int p[N];
int res[N];
int n,m;
int ans;
int ll,rr;
int main()
{
cin >> n >> m;
for(int i = 1;i <= n; ++i){
cin >> p[i];
res[i] = res[i - 1] + (p[i] == 1?1:0);
}
for(int l = 1,r = 1; r <= n; ++r){
while(r - l + 1 > m + res[r] - res[l - 1]) l++;
if(r - l + 1 > ans){
ans = r - l + 1;
ll = l;
rr = r;
}
}
cout << ans << endl;
for(int i = 1;i <= n; ++i){
if(i >= ll && i <= rr) cout << "1" << ' ';
else cout << p[i] << ' ';
}
return 0;
}
dfs时间复杂度O(n2)。会TLE
#include<iostream>
using namespace std;
const int N = 3e5 + 10;
int p[N];
int ans;
int res[N];
int n,k;
int check(){
int ans = 0;
int tot = 0;
for(int i = 1;i <= n;++i){
if(p[i] == 1) tot++;
else{
ans = max(tot,ans);
tot = 0;
}
}
ans = max(tot,ans);
return ans;
}
void dfs(int pos,int chance)
{
int i;
for(i = pos;i <= n;++i)
{
if(p[i] == 0 && chance != 0)
{
p[i] = 1;
dfs(i + 1,chance - 1);
p[i] = 0;
}
}
if(i > n){
int k = check();
if(k > ans)
{
ans = k;
for(int j = 1;j <= n; ++j) res[j] = p[j];
}
}
return;
}
int main(){
cin >> n >> k;
for(int i = 1;i <= n;++i) cin >> p[i];
dfs(1,k);
cout << ans << endl;
for(int i = 1;i <= n; ++i) cout << res[i] << ' ';
return 0;
}
二进制王国
进制王国是一个非常特殊的国家,因为该国家的居民仅由 0和1组成。
在这个国家中,每个家庭都可以用一个由 0和1组成的字符串S来表示,例如 101、000、111 等
现在,国王选了出 N 户家庭参加邻国的庆典。为了符合王国的审美标准,我们需要选择一种排排队顺序,使得最终形成的队伍在字典序上是最小的
国王将这个任务交给了你,请你解决这个问题
字符串排序
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<string>q;
int n;
string t;
bool cmp(string a,string b){
string c = a + b;
string d = b + a;
return c < d;
}
int main(){
cin >> n;
while(n--)
{
cin >> t;
q.push_back(t);
}
sort(q.begin(),q.end(),cmp);
for(int i = 0;i < q.size();++i) cout << q[i];
return 0;
}