专栏: 蓝桥杯——每日四道编程题(两道真题+两道模拟)
“蓝桥杯就要开始了,这些题刷到就是赚到”
₍ᐢ..ᐢ₎♡
另一个专栏: 蓝桥杯——每日四道填空题(两道真题+两道模拟题)
第一道真题(2022省赛B组):统计子矩阵
![](https://img-blog.csdnimg.cn/img_convert/eb6889e3827d24c3815f71a7c634e057.png)
这题采用前缀和+双指针可以优化到O(n^3),也能过~
![](https://img-blog.csdnimg.cn/img_convert/9c3d3a996fbc62bc9b3180ad9f8e9e8a.png)
#include <iostream>
using namespace std;
typedef long long ll;
int a[505][505] , k, m ,n;
ll res = 0; //总数会爆int
int main()
{
scanf("%d%d%d", &n, &m, &k);
for (int i = 1 ; i <= n ; ++i )
{
for (int j = 1 ; j <= m ; ++j ){
scanf("%d", &a[i][j]);
a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1]; //二维数组前缀和。
}
}
for (int p1 = 1 ; p1 <= m ; ++p1){ //划定左边界
for (int p2 = p1 ; p2 <= m ; ++p2){ // 划定右边界
for (int h1 = 1 , h2 = 1 ; h1 <= n ; ++h1) //h1 作为上边界,即子矩阵的高,h2 作为下边界,即子矩阵的底边
{
while (h2 <= h1 && a[h1][p2] - a[h1][p1-1] - a[h2-1][p2] + a[h2-1][p1-1] > k) ++h2; //不满足就逐渐缩小底边
if (h2 <= h1){
res += h1 - h2 + 1;
}
}
}
}
printf("%lld\n", res);
return 0;
}
第二道真题(2020省赛B组):回文日期
![](https://img-blog.csdnimg.cn/img_convert/b8b85f85534e28f34b8ab4a6db7b5f12.png)
这题如果你对日期数据不太熟悉,很容易做错的。这里就枚举每个数据就行了。
#include <iostream>
using namespace std;
bool isLeap(int y){
return (y%4==0&&y%100!=0)||(y%400==0);
}
bool check(int year,int month,int day){//判断是否为合法日期
if(month>12||month==0) return false;
if(day>31) return false;
if(month==2){
if(isLeap(year)&&day>29)
return false;
if(!isLeap(year)&&day>28)
return false;
}
if(month==4||month==6||month==9||month==11){
if(day>30) return false;
}
return true;
}
int main()
{
int n,i;
cin>>n;
int a,b,c,d,e,f,g,h;//8位数字
int year,month,day;
bool flag=false;
for(i=n+1;i<=99999999;i++){ //这里的数据要99999999注意
year=i/10000;
month=(i%10000)/100;
day=i%100;
a=i%10;
b=(i/10)%10;
c=(i/100)%10;
d=(i/1000)%10;
e=(i/10000)%10;
f=(i/100000)%10;
g=(i/1000000)%10;
h=(i/10000000)%10;
if(a==h && b==g && c==f && d==e && flag==false){
if(check(year,month,day)){
cout<<i<<endl;
flag=true;//只输出一个回文
}
}
if(a==h && b==g && c==f && d==e && a==c && b==d){
if(check(year,month,day)){
cout<<i<<endl;
break;
}
}
}
return 0;
}
上述也可以从年数开始枚举,然后分别构造日期和月份(0000 —— 1231),只是我认为这个题解看着很通俗易懂点。
第三道模拟题(2022年第四次模拟赛):插头
![](https://img-blog.csdnimg.cn/img_convert/79101a7045271b937c2e65562a495ab0.png)
![](https://img-blog.csdnimg.cn/img_convert/cecba361fe5562cb4b691ea118ed4d9d.png)
这题数据范围不大,分别暴力枚举两个矩阵看是否满足条件就行。
这里图解一下对于枚举的 A 和 B, B的位置与A位置的关系:
![](https://img-blog.csdnimg.cn/img_convert/4f2c9c55bf3ae39e7a50251fda16e833.png)
#include<iostream>
#include<string>
using namespace std;
string A[110], B[110];
int n, m, r, c;
bool nb(int a, int b) {
for(int i=0; i<r; i++) {
for(int j=0; j<c; j++) {
if(B[i][j]=='1'&&A[i+a][j+b]=='0') return false;
}
}
return true;
}
int main()
{
cin>>n>>m;
for(int i=0; i<n; i++) cin>>A[i];
cin>>r>>c;
for(int i=0; i<r; i++) cin>>B[i];
for(int a=0; a<=n-r; a++) {
for(int b=0; b<=m-c; b++ ) {
if(nb(a,b)) {
cout<<a+1<<" "<<b+1; //题目是从(1,1)开始的,这里是从(0,0)开始的
return 0;
}
}
}
cout<<"NO";
return 0;
}
收获:还是第一次用字符串数组来表示矩阵,真的很方便,学到了~
第四道模拟题(2022年第二次模拟赛)
![](https://img-blog.csdnimg.cn/img_convert/0e76525f529edd59694e5e79b6262021.png)
为了和第二题有联系,这里找了一道类似的题。
![](https://img-blog.csdnimg.cn/img_convert/d1b74bf47dcf0eefb8d5869311658bb5.png)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
string s;
bool check(string s) //回文串的查找
{
int i = 0, j = s.size() - 1;
while(i < j)
if(s[i ++] != s[j --])
return false;
return true;
}
int main()
{
std::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> s;
n = s.size();
for(int i = 0, len = n; i < n; i ++, len --)
{
string t = s.substr(i, len); //查找最长回文后缀
if(check(t))
{
string prev = s.substr(0, i);
string post = prev;
if(prev.size())
{
reverse(post.begin(), post.end());
cout << prev + t + post << endl;
return 0;
}
else
{
cout << t << endl; //该字符串本身就是回文字符串
return 0;
}
}
}
return 0;
}
![](https://img-blog.csdnimg.cn/img_convert/b0ab9abc697c7f499a1bc47cc9a9f29d.jpeg)