蓝桥杯集训·题解 week 1
农夫约翰的奶酪块
抽取一个方块之后,记录对于其所在行,列,竖的数量加+1
如果有行,列,竖的数量达到了n,则说明可以插入一个1*n的块
所以对答案贡献加+1
而我们注意到同一行的,列,竖坐标相同。相同的列,竖以此类推
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
int t;
int n,q;
map<pii,int>mp1,mp2,mp3;
void solve(){
cin>>n>>q;
int ans=0;
for(int i=1;i<=q;++i){
int x,y,z;
cin>>x>>y>>z;
mp1[{x,y}]++;
mp2[{y,z}]++;
mp3[{x,z}]++;
if(mp1[{x,y}]==n) ++ans;
if(mp2[{y,z}]==n) ++ans;
if(mp3[{x,z}]==n) ++ans;
cout<<ans<<endl;
} return ;
}
int main(){
t=1;
while(t--){
solve();
}
return 0;
}
哞叫时间
(写的有点shi)
不过核心思路是,枚举字符串里面每一个字符,然后将其改变成其他字符,最后统计改变,满足条件的字符串是否增加
因为改变一个字符,只会最多改变三个长度为3的字符串
点击查看代码
#include<bits/stdc++.h>
using namespace std;
map<string,int>mp;
int n,f;
string s;
int main(){
cin>>n>>f;
cin>>s;
set<string> cnt;
for(int i=0;i<n-2;++i){
string t;
if(s[i+1]==s[i+2] && s[i]!=s[i+1]){
t=s[i];t+=s[i+1];t+=s[i+2];
mp[t]++;
if(mp[t]>=f) cnt.insert(t);
// cout<<t<<endl;
}
}
for(int i=0;i<n;++i){
string ta,tb,tc,sa,sb,sc;
if(i>1){
if(s[i]==s[i-1]){
sa=s[i-2];sa+=s[i-1];sa+=s[i];
mp[sa]--;
}
}
if(i>0){
if(s[i]==s[i+1]){
sb=s[i-1];sb+=s[i];sb+=s[i+1];
mp[sb]--;
}
}if(i<n-2){
if(s[i+1]==s[i+2]){
sc=s[i];sc+=s[i+1];sc+=s[i+2];
mp[sc]--;
}
}
for(int j=0;j<=25;++j){
char c='a'+j;
if(c==s[i]) continue;
if(i>1 && c==s[i-1]){
ta=s[i-2];ta+=s[i-1];ta+=c;
if(mp[ta]+1>=f) cnt.insert(ta);
}
if(i>0 && c==s[i+1]){
tb=s[i-1];tb+=c;tb+=s[i+1];
if(mp[tb]+1>=f) cnt.insert(tb);
}
if(i<n-2 && s[i+1]==s[i+2]){
tc=c;tc+=s[i+1];tc+=s[i+2];
if(mp[tc]+1>=f) cnt.insert(tc);
}
}
if(i>1){
if(s[i]==s[i-1])
mp[sa]++;
}
if(i>0){
if(s[i]==s[i+1])
mp[sb]++;
}if(s[i+1]==s[i+2] && i<n-2){
sc=s[i];sc+=s[i+1];sc+=s[i+2];
mp[sc]++;
}
}
cout<<cnt.size()<<"\n";
for(auto i:cnt){
cout<<i<<"\n";
}
return 0;
}
蛋糕游戏
思维题
这道题应该是摸清题意,左右选择最大的,选取的方式是固定,但是合并的操作是要思考的,怎么合并能更大
长度为偶数
由于左右选择是第二步,所以,最后剩下两个时,合并后会吃掉,所以合并可以吃最多n/2+1个,左右吃是n/2-1个
无论如何左右选择,它吃的数量至少是n/2-1个,所以合并为了吃的蛋糕最多,一定要尽量吃n/2+1个
所以构建如下策略
a b c d e f g h
1.合并d,e
a b c {d e} f g h
2.吃掉max(a,h),假设h大
a b c {d e} f g {h}
1.合并d,e
a {b c d e} f g {h}
2.吃掉max(a,g),假设a大
{a} {b c d e} f g {h}
1.合并d,e
此时完成
由上我们可以发现,我们首先合并最中间的两个,当吃的选择一个方向之后,我们选择合并另一个方向靠近中间的两个
这样操作之后,合并的一定能吃够它吃的数量n/2+1个,达到最优解
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t;
int n;
const int maxn=5e5+10;
ll sum[maxn];
int a[maxn];
ll cnt=1e15;
void solve(){
cin>>n;
sum[0]=0;cnt=1e15;
for(int i=1;i<=n;++i) cin>>a[i],sum[i]=sum[i-1]+a[i];
for(int i=1;i+n/2<=n;++i){
cnt=min(cnt,sum[i+n/2]-sum[i-1]);
}
cout<<cnt<<" "<<sum[n]-cnt<<endl;
return ;
}
int main(){
cin>>t;
while(t--){
solve();
}
return 0;
}
哞叫时间II
找到一个长度为3的子数组满足后两个相等,第一个与后两个相等
所以,如果我们确定了一个子数组的第二个数,我们就可以任取,该数之前的所有不与其相等的数,就可以与他形成一个子数组
所以我们从后往前枚举,找到一个出现过两次的数,并记录他的位置
然后从前往后找,我们记录出现过不同的数的数量,如果遇到出现过两个数的位置,那么对答案产生贡献,注意如果在这之前还出现过该数,需要-1
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n;
const int maxn=1e6+10;
int a[maxn];
int mp[maxn];
bool book[maxn];
ll ans=0;
ll cnt=0;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=n;i>=1;--i){
if(mp[a[i]]==0) mp[a[i]]=-1;
else if(mp[a[i]]==-1){
mp[a[i]]=i;
}
}
for(int i=1;i<n;++i){
if(mp[a[i]]==i){
ans+=cnt+(book[a[i]]?-1:0);
}
if(book[a[i]]) continue;
book[a[i]]=1;
++cnt;
}
cout<<ans<<endl;
return 0;
}
奶牛体检
纯粹的暴力,一定会超时
我们考虑一种翻转方式,如果翻转了(i,j),那我们再去翻转(i-1,j+1),那么此时只用考虑i-1和j+1的位置交换后是否能够匹配
所以这样就避免了,翻转过的再翻转,降低了时间复杂度
具体实现:
如果一个区间是奇数长度,我们从i点扩展成(i-1,i+1)
如果一个区间是偶数长度,我们从(i,i+1)点扩展成(i-1,i+2)
此题给了我们暴力枚举所有的(i,j)数对,优化的暴力枚举方法
这样的枚举方法,能够更有效地统计对答案的贡献
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n;
const int maxn=1e6+10;
ll cnt=0;
int a[maxn],b[maxn];
ll ans[maxn];
int main(){
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i){
cin>>b[i];
if(a[i]==b[i]) ++cnt;
}
for(int i=1;i<=n;++i)
for(int j=0;j<=1;++j){
ll sum=cnt;
for(int l=i,r=i+j;l>=1 && r<=n;++r,--l){
if(a[l]==b[l]) --sum;
if(a[r]==b[r]) --sum;
if(a[l]==b[r]) ++sum;
if(a[r]==b[l]) ++sum;
ans[sum]++;
}
}
for(int i=0;i<=n;++i) cout<<ans[i]<<"\n";
}
本文作者:归游
本文链接:https://www.cnblogs.com/guiyou/p/18739567
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步