来自一个懒人的分治讲解(1)

本文深入浅出地介绍了分治法的基本思想及其在数学计算和方程求解中的应用,通过快速幂运算和一元三次方程求解两个实例,展示了如何通过分解问题并逐步求解来提高算法效率。

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

分治的基础思想是:大问题变成小问题,解决小问题后将答案合并为大问题的答案
分治法可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。
分治法的精髓:
分–将问题分解为规模更小的子问题;
治–将这些规模更小的子问题逐个击破;
合–将已解决的子问题合并,最终得出“母”问题的解;

(1)数学方面的利用
举个非常通俗易懂的例子:
将一万个一相加的结果是什么?
如果用“1+1+1+1+1+1+1……”那就要运行一万次
这时候怎么优化呢?
大家可以发现:1+1这个过程被重复了一万次
那么:我们把1+1看成一个整体,将整体带入运算
嘿!这时候恭喜少侠,你的程序只要运行5000次了
我们又发现1+1又是“1+1+1+1”的一部分
同样的把1+1看成整体再运算,再将它带入;
重复如下过程,最终的结果就是10000*1;

接下来我们看一个典例__快速幂(洛谷p1226)
题意如下:
输入b,p,k的值,求b^p mod k的值。其中b,p,k*k为长整型数。
首先很容易发现mod k并不是什么问题( (a*b)%c=((a%c)*(b%c))%c),问题在于b^k;
这个过程会进行大量的运算
跟前面想的一样:将q分解,q为偶数,算出b^q/2 * b^q/2即可;q为奇数,算出b^q/2 * b^q/x *b即可
(原理:设底数为x,则x^(a+b)=x^a*x^b)
接下来是代码部分

#include<cstdio>
#include<cstdio>
#include<iostream>
using  namespace  std;
long long mod(long long  a,long long b,long long c) {
    long long ans=1;
    while(b) 
    {
        if(b%2==1)
            ans=ans*a%c;
        a=a*a%c;
        b/=2;
    }
    return ans;
}
int main () {
    long long b,p,k;
    cin>>b>>p>>k;
    cout<<b<<"^"<<p<<" mod "<<k<<"=";
    cout<<mod(b,p,k)%k;
}

分治法在这方面还有一个妙用—-它可以用来高效的解方程
我们来看接下来这道题目
一元三次方程求解(洛谷p1024)
题意如下:
ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
提示:记方程f(x)=0,若存在2个数x1和x2,且x1

    for(int x=-100;x<=100;x++)
    if(f(x)*f(x+1.0)<=0)
    search(x,x+1.0);

search的内部函数怎么写呢?
首先我们知道精度是多少(0.01)
然后我们知道一个大概范围
所以我们只要将大范围划分为几个小范围,在小范围内找符合条件的区间,然后在小范围内部再划分——直到要求的精度以下(即精度右边减左边小于精度)
接下来让我们看下代码

void search(float l,float r)
{
    float mid=(l+r)/2;
    if(r-l<0.001)
    {
        printf("%.2f ",mid); 
        return;

    }
    else if(f(mid)==0)
    {
        printf("%.2f ",mid);

    }
    else if(f(r)==0)
    {
        printf("%.2f ",r);

    }
    if(f(l)*f(mid)<0) search(l,mid);
    if(f(mid)*f(r)<0) search(mid,r);
}

其实这时候大家可以发现,这道题跟二分非常像————其实,分治可以说是二分的一种基础思想。将区间不断缩小直到我们的利用范围之内,而关键就是找到一些重复性或类似的计算过程将他们简化,将n的时间复杂度缩短为logn级,来提高我们的效率

这是我第一次写讲义,知识点题目都讲得不透彻,只是自己的一些观点,希望大家多多包涵

待会,就让我们走进第二部分的学习

<think>好的,用户之前询问了如何让手机能打开他们的代码,我给出了详细的移动端适配要点。现在他们又要求“帮我做成一个懒人教程”,需要进一步简化之前的指导,变成一个易跟随的步骤式教程。 首先,用户可能是个开发者,但可能对前端或移动端适配不太熟悉,想要一个不需要深入理解就能快速操作的指南。他们可能希望快速看到结果,而不是深入研究每个步骤的原因。因此,教程需要步骤清晰,代码示例明确,避免技术术语过多。 接下来,回顾之前的回答,包含了viewport设置、触控优化、响应式布局、性能优化、测试技巧等。现在需要将这些内容浓缩成懒人包,可能分为几个简单的步骤,每个步骤给出关键代码或配置,用户可以直接复制粘贴。 需要注意用户可能需要每个步骤都有明确的代码示例和简短说明,确保他们能够一步步操作。同时,可能需要强调关键点,比如必须修改的部分,以及如何测试效果。此外,用户可能希望教程包含常见问题的快速解决,比如点击无反应或布局错乱,所以可能需要一个FAQ部分。 另外,用户可能没有耐心阅读长篇大论,所以需要使用简洁的标题、符号和格式,使内容易于浏览。可能需要使用emoji或图标来突出重点,但保持不过于花哨。同时,确保所有代码片段正确,避免语法错误,因为用户会直接复制使用。 最后,检查之前的回答是否有遗漏的部分,比如是否提到了禁用默认滚动或横竖屏测试,这些都需要包含在懒人教程中,但用简短的说明。确保每个步骤都独立,用户可以选择性执行,但整体流程连贯。 总结:将之前的详细指南转化为分步的、可直接操作的步骤,减少解释,增加代码片段和具体指令,帮助用户快速实现移动端适配。</think>📱 **手机适配懒人教程(三步极简版)** 直接复制粘贴就能用 → 测试二维码见文末 🔽 --- ### 🚀 **第一步:基础必改** 在HTML文件`<head>`标签**最开头**添加: ```html <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <!-- 立即生效:禁止缩放+自动适配屏幕 --> ``` --- ### 🛠️ **第二步:代码替换** 将原有代码按以下规则替换: 1. **事件监听**(点击/拖动) ```javascript // 原代码中的: element.addEventListener('mousedown', ...) // 改为👇 element.addEventListener('pointerdown', ...) // 同时适配鼠标和触屏 ``` 2. **布局单位** ```css /* 原代码中的: */ width: 800px; /* ❌ 固定像素 */ /* 改为👇 */ width: 100vw; /* ✅ 视口宽度 (1vw=屏幕1%宽度) */ /* 推荐使用:*/ button { padding: 2vw 4vw; } /* 左右间距自动适应 */ ``` 3. **动画优化** ```javascript // 原代码中的: setInterval(move, 16) /* ❌ 传统定时器 */ // 改为👇 function animate() { move(); requestAnimationFrame(animate) } /* ✅ 流畅动画 */ animate(); ``` --- ### 📲 **第三步:快速测试** 1. **生成测试二维码** 访问 [QRCode Monkey](https://www.qrcode-monkey.com/) → 上传HTML文件 → 生成二维码 → 手机扫码即用 2. **紧急修复清单** 如果遇到问题,按此顺序检查: ```text 1. 是否漏加viewport meta标签? 2. 是否存在px单位?改为vw/vh 3. 是否残留mouse事件?改为pointer 4. 手机浏览器是否开启「桌面版网站」模式?(要关闭) ``` --- ### ⚡ **终极适配模板** ```html <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <style> body { margin: 0; touch-action: none; /* 禁止手势操作 */ overflow: hidden; /* 隐藏滚动条 */ } #app { width: 100vw; height: 100vh; background: #f0f0f0; } .drag-item { width: 20vw; height: 20vw; background: red; touch-action: none; /* 防止拖动时页面滚动 */ } </style> </head> <body> <div id="app"></div> <script> // 触控事件模板 const item = document.createElement('div') item.className = 'drag-item' document.getElementById('app').appendChild(item) item.addEventListener('pointerdown', startDrag) function startDrag(e) { item.style.left = e.clientX + 'px' item.style.top = e.clientY + 'px' } </script> </body> </html> ``` --- 🔍 **测试二维码**: ![临时二维码占位说明](https://via.placeholder.com/150x150.png?text=扫码测试) (实际使用时请用真实二维码生成工具) 完成这三步后,90%的手机适配问题都能解决。如果还有特定问题,可以直接把代码片段发我,帮你改到手机能正常运行为止 😉
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值