枚举刷题记录

最大正方形
由于数据范围很小,可以开多重循环。
一开始没有思路,后来发现只要知道左上角和右下角的点就可以确定一个正方形,枚举即可。(中点+全等)
注意判断边长大小的时候采用sqrt会有精度的问题,需要直接用平方避免误差。

#include<bits/stdc++.h>
#define endl '\n'
#define pii pair<int,int>

using namespace std;

const int maxn = 103;
char a[maxn][maxn];

void solve()
{
    int xa,xb,xc,xd;
    int ya,yb,yc,yd;
    int n; cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            for(int x=i+1;x<n;x++)
            {
                for(int y=j+1;y<n;y++)
                {
                    if(a[i][j]=='#'&&a[x][y]=='#')
                    {
                        double midx=(i+x)/2.0;
                        double midy=(j+y)/2.0;
                        double detx=x-midx;
                        double dety=y-midy;
                        int ax=midx+dety;
                        int ay=midy-detx;
                        int bx=midx-dety;
                        int by=midy+detx;
                        if(ax!=midx+dety||ay!=midy-detx||bx!=midx-dety||by!=midy+detx)
                        continue;
                        if(ax>=0&&ay>=0&&ax<n&&ay<n&&bx>=0&&bx<n&&by>=0&&by<n)
                        {
                            if(a[ax][ay]=='#'&&a[bx][by]=='#')
                            {
                                int temp=(x-ax)*(x-ax)+(y-ay)*(y-ay); // 不要用sqrt
                                if(temp>ans)
                                {
                                    ans=temp;
                                    xa=i,ya=j;
                                    xb=bx,yb=by;
                                    xc=ax,yc=ay;
                                    xd=x,yd=y;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    cout<<xa+1<<" "<<ya+1<<endl;
    cout<<xc+1<<" "<<yc+1<<endl;
    cout<<xb+1<<" "<<yb+1<<endl;
    cout<<xd+1<<" "<<yd+1<<endl;
    return ;
}

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T; T=1;
    while(T--) solve();
    return 0;
}

回文日期
首先确定枚举对象,由于回文数的性质,我们可以枚举年份来推出月份和日期,但这样枚举需要处理的细节较多也很麻烦。

#include<bits/stdc++.h>
#define endl '\n'
#define pii pair<int,int>

using namespace std;

bool pd(int year)
{
    if(year%4==0&&year%100!=0) return true;
    else if(year%400==0) return true;
    else return false;
}

int month1[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; // 平年
int month2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}; // 闰年

void solve()
{
    string l,r;
    cin>>l>>r;
    int start=(l[0]-'0')*1000+(l[1]-'0')*100+(l[2]-'0')*10+(l[3]-'0');
    int end=(r[0]-'0')*1000+(r[1]-'0')*100+(r[2]-'0')*10+(r[3]-'0');
    int cnt=0;
    int lmonth=(l[4]-'0')*10+(r[5]-'0');
    int lday=(l[6]-'0')*10+(l[7]-'0');
    int rmonth=(r[4]-'0')*10+(r[5]-'0');
    int rday=(r[6]-'0')*10+(r[7]-'0');    
    for(int i=start;i<=end;i++)
    {
        int temp=i;
        int month=0,day=0;
        month+=temp%10; temp/=10; month*=10;
        month+=temp%10; temp/=10;
        day+=temp%10; temp/=10; day*=10;
        day+=temp; 
        // cout<<month<<" "<<day<<endl;
        if(i==start)
        {
            if(month<lmonth)
            continue;
            if(month==lmonth&&day<lday)
            continue;
        }
        if(i==end)
        {
            if(month>rmonth)
            continue;
            if(month==rmonth&&day>rday) 
            continue;
        }
        bool sig=pd(i);
        if(sig) // 闰年
        {
            if(month<=12&&month>0&&day<=month2[month]&&day>0) cnt++;
        }
        else
        {
            if(month<=12&&month>0&&day<=month1[month]&&day>0) cnt++;            
        }
    }
    cout<<cnt<<endl;
    return ;
}

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T; T=1;
    while(T--) solve();
    return 0;
}

实际上,我们可以枚举月份和日期来反推年份,可以发现2月有29天时对应的回文数是92200229,由于9220是闰年,因此不需要判断年份是不是闰年,将2月设置成29天枚举即可。

#include<bits/stdc++.h>
#define endl '\n'
#define pii pair<int,int>

using namespace std;

int day[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};

void solve()
{
    int l,r; cin>>l>>r;
    int ans=0;
    for(int i=1;i<=12;i++)
    {
        for(int j=1;j<=day[i];j++)
        {
            int temp=(j%10)*1000+(j/10)*100+(i%10)*10+i/10;
            temp*=10000; 
            temp+=i*100+j;
            if(temp>=l&&temp<=r) ans++;
        }
    }
    cout<<ans<<endl;
    return ;
}

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T; T=1;
    while(T--) solve();
    return 0;
}
### 蓝桥杯C语言B组备考指南 #### 备考资料推荐 为了更好地准备蓝桥杯C语言B组竞赛,建议参考官方发布的历年真集以及各类在线资源。特别是第十一届蓝桥杯的真被广泛认为具有较高的代表性[^1]。此外,在线平台如LeetCode、牛客网提供了大量的算法练习机会,有助于提升编程技能。 #### 练习目精选 重点在于掌握基础数据结构与常用算法的应用。例如广度优先搜索(BFS)/深度优先搜索(DFS),还有简单的动态规划(DP)问均会在比赛中频繁出现。对于较长且复杂的字符串处理类目,像统计字符频率这样的操作也需要熟练掌握[^3]。 ```cpp #include <iostream> #include <map> using namespace std; int main() { string s; cin >> s; map<char,int> m; // 记录每个字母出现次数 for(auto c : s){ ++m[c]; } char max_char = 'a'; int max_count = 0; // 找到出现次数最多且字典序最小的字母 for(const auto& p:m){ if(p.second > max_count || (p.second==max_count && p.first<max_char)){ max_char=p.first; max_count=p.second; } } cout << max_char << " " << max_count; } ``` 此段代码展示了如何找出给定字符串中最常出现的小写字母及其频次,并按照要求返回字典顺序最小的结果。 #### 解技巧分享 面对较难目时可尝试简化模型或采用暴力枚举法验证部分情况;而对于填空型试,则需注重细节并灵活运用已知条件快速得出结论。值得注意的是,近年来蓝桥杯赛难度逐年增加,尤其是最后几道编程大往往涉及较为复杂的状态转移方程设计[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值