蓝桥杯冲刺

1、贪心算法
1、反悔性质的
priority_queue用法:
定义priority_queue<元素类型, 底层容器类型, 比较函数对象类型> 队列名;
推荐洛谷:P2949 ——绿题> https://www.luogu.com.cn/problem/P2949
(2)比较函数:greater(小顶堆)、less(大顶堆)
自定义:struct CompareTask { bool operator()(const Task& a, const Task& b) { return a.priority > b.priority; } };
(3)适用题目:Top K问题、合并K个有序链表、Dijkstra算法(最短路)

注意ans有时初始化为0

2、位运算
unsigned int x=n&0xffff; unsigned int high=n>>16;

3、cin cout输入输出流
洛谷P1469找筷子问题,用cin cout写会超时,因为在C++中,cin和cout默认与C标准输入输出流保持同步(ios::sync_with_stdio(true)),这会带来额外的性能开销。此外,cout在输出时会先将数据存入缓冲区再刷新,而大量数据的缓冲操作会显著降低效率。相比之下,scanf和printf是C语言中更底层的格式化输入输出函数,没有流同步和缓冲区管理的额外步骤,因此在处理大规模数据时速度更快。
可添加ios::sync_with_stdio(false); cin.tie(0);可提高速度。或者用scanf printf

4、枚举
回文质数:有偶数位的回文数都不会是质数,除了11
洛谷p1217,谨防tle,需要对左端点进行偶数剔除,然后左右端点间每次+2来遍历,减少时间损失。

回文的判断代码 从1-n个数,第i个和第n+1-i个数应是相同的:一个 8 位数字是回文的,当且仅当对于所有的 i(1≤i≤8)从左向右数的第 i 个数字和第 9−i 个数字(即从右向左数的第 i 个数字)是相同的。 ``` Int flag=1; while(s>0){ a[flag]=s%10; s/=10; flag++; } for(i=0;i<=flag/2;i++){ if(a[i]!=a[flag-i]) return false; } ```

(2)回文日期
洛谷p2010
更好的题解:找出回文日期看看是否在区间内,可以列举所有月份和其天数,生成回文的年份。闰月0229反过来的9220是闰年。但我的题解是正向思路,判断年月日是否合理,判断回文。

正向思路代码
#include<bits/stdc++.h>
using namespace std;
int hui(int x){
    int flag=1,a[15],i=8;
    while(x>0){
        a[flag]=x%10;
        x/=10;
        flag++;
    }
        if(a[1]==0||a[2]>=4||(a[3]>=3&&a[4]==1)||a[4]>=2) return 0;//判断不合理的月份日期
    int year=0,month=0,day=0;
    while(i>=5){
        year=year*10+a[i];
        if(i>=7) month=month*10+a[i-4];
        if(i>=7) day=day*10+a[i-6];
        i--;
    }
    int d[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};
    int j=0;
    if(year%4==0&&year%100!=0||year%400==0) j=1;
    if(day>d[j][month]) return 0;
    
    for(int i=1;i<=flag/2;i++){
        if(a[i]!=a[flag-i]) return 0;
    }return 1;
}
int main(){
    int x1,x2,i,ans=0;
    cin>>x1>>x2;
    for(i=x1;i<=x2;i++){
        if(!hui(i)) continue;
        ans++;
    }
    printf("%d",ans);
    return 0;
}

5、前缀和
(1)又忘记前缀和咋写了qwq
记个比较的最小值:ans=-2147483647
(2)洛谷子序列p3131
思路:对于每个前缀和,最后一个数为当前i,记录其与7的模。模相同的进行比较,是当前max还是i-之前同一个模的位置的值大。
余数相同的前缀和,作差后可整除7,所含元素即两个前缀和所答i之差。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,i;
    cin>>n;
    int sum[n+1],max1=0;
    sum[0]=0;
    for(i=1;i<=n;i++){
        cin>>sum[i];
        sum[i]+=sum[i-1];
        sum[i]%=7;
    }
    int vis[7];
    memset(vis,-1,sizeof(vis));
    vis[0]=0;//若能整除7,则所在位置是i-0
    for(i=1;i<=n;i++){
        int r=sum[i]%7;
        if(vis[r]==-1) vis[r]=i;
        else{
            max1=max(max1,i-vis[r]);
        }
    }
    cout<<max1;
    return 0;
}

6、二分
洛谷p1783砍树:这种答案不一定是数组中的某一个数时,不需要二分数组坐标,直接二分每个树的高度即可

点击查看核心代码
while(l<=r){    //左右端点作为结束条件
        curr=(l+r)/2;
        sum=0;
        for(auto &it:w){
        if(it>curr) sum+=it-curr;
    }
        if(sum<m) r=curr-1;    //不够就让树再矮一点,在左半部分遍历
        else l=curr+1;            //超了就让树高一点
        }

洛谷p2678——有点难

posted on 2025-05-26 16:03  Siannnn  阅读(30)  评论(0)    收藏  举报