道路和航路 蓝桥真题

博客围绕蓝桥最短路问题展开,因存在负权边,采用SPFA算法但只能得95分。主要记录了SPFA的两种优化方法,一是SLF,用双端队列,根据点与队首点大小关系决定入队位置;二是LLL,在弹出队首点时,若其平均值大于队列所有点平均值则扔至队尾。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://lx.lanqiao.cn/problem.page?gpid=T22

因为有负权边 只能用spfa 但是数据比较强 只能做到95分。。 可能有其他方法吧

主要记一下spfa两种优化

第一种是SLF 就是改用双端队列 当一个点v入队列时 判断其和队首点front的大小关系 如果队列为空或者dis[v]>=dis[front] 则把v扔到队尾 否则扔到队首

第二种是LLL 在循环开始处弹出队首点时 如果当前队首点的平均值大于队列中所有点的平均值 则将其扔至队尾 直至当前队首的点小于等于平均值 才真正将其弹出队列

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=0x3f3f3f3f;
const int maxn=3e4+10;
const int maxm=5e4+10;

struct node
{
    int v,w,next;
};

deque <int> que;
node edge[3*maxm];
int first[maxn],dis[maxn],book[maxn];
int n,m1,m2,s,num;

template <class T>
inline void _cin(T &ret)		//读正负整数 (int, long long)
{
    char ch;
    int flag = 0;
    while((ch = getchar()) < '0' || ch > '9')
    {
        if(ch == '-') flag = 1;
    }
    for(ret = 0; ch >= '0' && ch <= '9'; ch = getchar())
    	ret = ret * 10 + ch - '0';
    if(flag) ret *= -1;
}

void addedge(int u,int v,int w)
{
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=first[u];
    first[u]=num++;
}

void spfa()
{
    ll sum;
    int i,u,v,w,cnt;
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0,book[s]=1;
    que.push_back(s);
    cnt=1,sum=0;
    while(!que.empty()){
        u=que.front();
        while(ll(cnt)*ll(dis[u])>sum){
            //printf("*%d*\n",u);
            que.pop_front();
            que.push_back(u);
            u=que.front();
        }
        que.pop_front();
        book[u]=0;
        cnt--,sum-=dis[u];
        for(i=first[u];i!=-1;i=edge[i].next){
            v=edge[i].v,w=edge[i].w;
            if(dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                if(!book[v]){
                    book[v]=1;
                    if(que.empty()||dis[v]>dis[que.front()]) que.push_back(v);
                    else que.push_front(v);
                    cnt++,sum+=dis[v];
                }
            }
        }
    }

}

int main()
{
    int i,u,v,w;
    //scanf("%d%d%d%d",&n,&m1,&m2,&s);
    _cin(n),_cin(m1),_cin(m2),_cin(s);
    memset(first,-1,sizeof(first));
    num=0;
    for(i=1;i<=m1;i++){
        //scanf("%d%d%d",&u,&v,&w);
        _cin(u),_cin(v),_cin(w);
        addedge(u,v,w);
        addedge(v,u,w);
    }
    for(i=1;i<=m2;i++){
        //scanf("%d%d%d",&u,&v,&w);
        _cin(u),_cin(v),_cin(w);
        addedge(u,v,w);
    }
    spfa();
    for(i=1;i<=n;i++){
        if(dis[i]==N) printf("NO PATH\n");
        else printf("%d\n",dis[i]);
    }
    return 0;
}

 

<think>好的,我现在需要处理用户关于蓝桥杯竞赛中浮点数处理的真题或解法的请求。首先,我要确认用户的具体需求:他们可能在寻找蓝桥杯历年真题中涉及浮点数处理的题目,以及相应的解决方法。接下来,我需要回忆蓝桥杯的常见题型,尤其是Python组的题目,因为用户提供的引用中提到了Python组的情况。 根据引用[1][2],蓝桥杯青少组省赛的题目难度适中,但需要扎实的基础。浮点数处理通常涉及精度控制、四舍五入、避免累积误差等问题。常见的考点可能包括格式化输出、小数运算技巧、比较浮点数时的注意事项等。 我需要先整理几个典型的蓝桥杯浮点数处理题目。例如,可能存在要求计算特定数学问题并保留小数位数的情况,或者处理浮点数的输入输出格式。此外,可能还有涉及避免浮点数计算误差的题目,比如使用整数运算代替浮点数运算来保持精度。 接下来,针对每个题目类型,我需要给出具体的解决方法代码示例。例如,使用Python的round函数进行四舍五入,或者使用decimal模块处理高精度计算。同时,要注意蓝桥杯竞赛中可能对输出格式的严格要求,比如必须保留两位小数,这时候需要正确的格式化字符串方法。 另外,用户提供的引用中提到,即便是后一个大题,实现起来也不难,关键在于理解题意并转换为代码。因此,在解答时,可能需要强调问题分析将问题分解为编程步骤的能力。 后,生成相关问题时要围绕浮点数处理的不同方面,比如精度控制、运算优化、常见错误等,帮助用户全面了解该考点。</think>### 蓝桥杯浮点数处理真题及方法 #### 典型真题示例 1. **保留小数位数问题** **题目**:计算圆的面积,保留7位小数(输入半径$r$,输出面积$S$)[^1]。 **解法**:使用Python的字符串格式化或`round`函数。 ```python import math r = float(input()) S = math.pi * r ** 2 print("{:.7f}".format(S)) # 直接格式化输出 # 或 print(round(S, 7)) # 注意:round可能末尾补零不足需处理 ``` 2. **浮点数精度陷阱** **题目**:判断两个浮点数$a$$b$是否相等,若$|a - b| < 1e-9$则认为相等[^2]。 **解法**:避免直接`a == b`,改用误差范围判断。 ```python a = float(input()) b = float(input()) if abs(a - b) < 1e-9: print("相等") else: print("不等") ``` 3. **浮点数运算转整数优化** **题目**:计算浮点数数组平均值,保留两位小数(例如:输入`[1.2, 3.4, 5.6]`,输出`3.40`)。 **解法**:利用整数运算避免累积误差。 ```python nums = list(map(float, input().split())) total = sum(int(x * 100) for x in nums) # 转为分计算 avg = total / len(nums) print("{:.2f}".format(avg / 100)) ``` #### 核心技巧总结 1. **输出格式化** - 使用`format`函数:`"{:.Nf}".format(x)`保留$N$位小数。 - 注意补零:如要求必须显示两位小数,即使末尾是零(例如`3.4`需输出`3.40`)。 2. **高精度计算** - 需要精确小数时,用`decimal`模块: ```python from decimal import Decimal, getcontext getcontext().prec = 20 # 设置精度位数 result = Decimal('0.1') + Decimal('0.2') # 精确计算0.3 ``` 3. **避免浮点误差** - 比较时用误差阈值(如`1e-9`)。 - 涉及货币、分数时,优先转为整数计算(如以分为单位)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值