算法竞赛宝典-分治算法

/*分治*/


/*
#include <iostream>
using namespace std;



int main()
{

    return 0;
}
*/



/*第k小数1
#include <iostream>
#include <algorithm>
using namespace std;

int n,k,i,j,l;
int a[10000+10],b[10000+10];

int cmp(int x,int y);
void Swap();
void F(int START,int END);

int main()
{
    int n,k;
    cin>>n>>k;
    for(i=1;i<=n;i++)
    {
        cin>>b[i];
        a[i]=b[i];
    }
    for(i=6;i<=n+1;i=i+5)
    {
        sort(a+i-5,a+i,cmp);
    }
    for(i=1;i<=n/5;i++)
    {
        swap(a[i],a[i*5-2]);
    }
    sort(a+1,a+i,cmp);
    swap(a[1],a[i/2]);
    F(1,n);
    return 0;
}
int cmp(int x,int y)
{
    return x<y;
}

void Swap()
{
    swap(a[i],a[j]);
    swap(i,j);
}

void F(int START,int END)
{
    i=START;
    j=END;
    while(i!=j)
    {
        if(i<j)
        {
            if(a[i]<a[j])
                Swap();
            else j--;
        }
        else
        {
            if(a[i]>a[j])
                Swap();
            else j++;
        }
    }
    if(i<k)
        F(i+1,END);
    else if(i>k)
        F(START,i-1);
    else{
        for(l=1;l<=n;l++)
        {
            if(a[i]==b[l])
            {
                cout<<l<<endl;
                break;
            }
        }
    }
}*/



/*第k小数1
#include <iostream>
#include <algorithm>
using namespace std;

int n,k;
int a[10000+10],b[10000+10];

void Swap(int i,int j);
void F(int START,int END);

int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>b[i];//原数组
        a[i]=b[i];//负责交换的数组
    }
    F(1,n);
    return 0;
}

void F(int START,int END)
{
    int i=START;
    int j=END;
    while(i!=j)
    {
        if(i<j)
        {
            if(a[i]>a[j])
                Swap(i,j);
            else j--;
        }
        else{
            if(a[i]<a[j])
                Swap(i,j);
            else j++;
        }
    }
    if(i<k) F(i+1,END);
    else if(i>k) F(START,i-1);
    else{
        for(int l=1;l<=n;l++)
        {
            if(a[i]==b[l])
            {
                cout<<l<<endl;
                break;
            }
        }
    }
}

void Swap(int i,int j)
{
    swap(a[i],a[j]);
    swap(i,j);
}
*/



/*第k小数1
#include <iostream>
using namespace std;

int a[10000+10],b[10000+10];

int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        b[a[i]]=i+1;
    }
    for(int i=0;i<n-1;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            if(a[j]<a[i])
            {
                int t=a[j];
                a[j]=a[i];
                a[i]=t;
            }
        }
    }
    cout<<b[a[k-1]]<<endl;
    return 0;
}*/




/*解一元二次方程
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    double a,b,c,d;
    cin>>a>>b>>c>>d;
    for(int i=-10000;i<=10000;i++)
    {
        double x=i/100.0;
        double f=a*x*x*x+b*x*x+c*x+d;
        if(f>=-0.01&&f<=0.01)
            cout<<fixed<<setprecision(2)<<x<<endl;
    }
    return 0;
}*/



/*残缺棋盘*/




/*循环比赛
#include <iostream>
#include <iomanip>
using namespace std;

int a[32+10][32+10];

int main()
{
    int m;
    cin>>m;

    a[1][1]=1;//初始的右上

    int n=1;
    for(int i=1;i<=m;i++)
        n*=2;

    int h=1;

    do{
        for(int i=1;i<=h;i++)
        {
            for(int j=1;j<=h;j++)
            {
                a[i][j+h]=a[i][j]+h;//左上
                a[i+h][j]=a[i][j+h];//右下
                a[i+h][j+h]=a[i][j];//左下
            }
        }
        h*=2;
    }while(h!=n);

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cout<<setw(4)<<a[i][j];
        }
        cout<<endl;
    }

    return 0;
}
*/


/*P1226 【模板】快速幂||取余运算
#include <iostream>
using namespace std;

long long int mi(long long int x,long long int n,long long int k);

int main()
{
    long long int x,n,k;
    cin>>x>>n>>k;
    if(x==k)
        cout<<x<<"^"<<n<<" mod "<<k<<"=0"<<endl;
    else{
        long long int xx=x%k;
        long long int y=mi(xx,n,k);
        cout<<x<<"^"<<n<<" mod "<<k<<"="<<y<<endl;
        return 0;
    }
}
long long int mi(long long int x,long long int n,long long int k)
{
    if(n==1) return x;
    long long int c=mi(x,(n>>1),k);
    if((n&1)==0)
        return (c*c)%k;
    else
        return (c*c*x)%k;

}*/



/*位优化快速幂算法
#include <iostream>
using namespace std;

int mi(int x,int n);

int main()
{
    int x,n;
    cin>>x>>n>>k;
    cout<<mi(x,n)<<endl;
    return 0;
}
int mi(int x,int n)
{
    if(n==1)
        return x;
    else
    {
        int c=mi(x,n>>1);//不能有=
        if((n&1)==0)//括号不能少
            return c*c;
        else
            return c*c*x;
    }
}
*/




/*基本快速幂算法
#include <iostream>
using namespace std;

int mi(int x,int n);

int main()
{
    int x,n;
    cin>>x>>n;
    cout<<mi(x,n)<<endl;
    return 0;
}
int mi(int x,int n)
{
    if(n==1)
        return x;
    else{
        int c=mi(x,n/2);
        if(n%2==0)
            return c*c;
        else{
            return c*c*x;
        }
    }
}*/



/*逃亡
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    double s,a,b;
    cin>>s>>a>>b;
    double c,c0=0,c1=s;
    double t1,t2,t3,t4;
    do{
        c=(c1-c0)/2.0+c0;
        t3=c/b;
        t1=t3+(s-c)/a;
        t4=(c-t3*a)/(a+b);
        t2=t3+t4+(s-(t3+t4)*a)/b;
        if(t1<t2)
            c1=c;
        else c0=c;
    }while(fabs(t1-t2)>1e-4);
    cout<<t1<<endl;
    return 0;
}
*/

/*魔法石的诱惑
#include <iostream>
using namespace std;

int f(int x);

int main()
{
    int q;
    cin>>q;
    int start=1;
    int end=500000000;
    int ans=end+1;
    while(start<=end)
    {
        int mid=(end-start)/2+start;
        int qq=f(mid);
        if(qq==q&&mid<ans)
        {
            ans=mid;
        }
        if(qq>q)
            end=mid-1;
        else if(qq<q)
            start=mid+1;
        else end=mid-1;
    }
    cout<<ans<<endl;
    return 0;
}

int f(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=x/5;
        x/=5;
    }
    return ans;
}
*/

/*折半查找法
#include <iostream>
using namespace std;

int a[10000+10];

int search(int x,int y,int z);

int main()
{
    int n,m;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    cin>>m;
    search(1,n,m);
    return 0;
}
int search(int x,int y,int z)
{
    int mid=(x+y)/2;
    if(z>a[y]||z<a[x])
        cout<<"-1"<<endl;
    else{
        if(z==a[mid]) cout<<mid<<endl;
        else if(z>a[mid]) search(mid+1,y,z);
        else search(x,mid-1,z);
    }

}
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值