zoukankan      html  css  js  c++  java
  • hdu 5014 思维题/推理

    http://acm.hdu.edu.cn/showproblem.php?pid=5014

    从小数開始模拟找方法规律,然后推广,尤其敢猜敢尝试,错了一种思路继续猜-----这是一种非常重要的方法啊

    这道题还是从小数開始模拟,我是依据16以内的找的规律

    依据

    2^k---2^k-1

    2^k+1---2^k-2

    ...

    这样陪下去

    当2^k==n的时候,

    从2^(k-1)按相同的方法配下去,

    WA了非常久,是lower_bound用错了 只是没明确为啥  换成upper_bound也能够AC....但还不明确为啥lower_bound  WA......

    目的是找以一个<=n的下标
    int id=lower_bound(mi,mi+17,n)-mi; 
    if(mi[id]>n)id--;
    跟
    int id=16;
    while(mi[id]>n && id>=0)id--;
    不一样么?后者AC   前者WA。。

    以下是AC代码

    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <map>
    #include <set>
    #include <queue>
    using namespace std;
    
    #define ls(rt) rt*2
    #define rs(rt) rt*2+1
    #define ll long long
    #define ull unsigned long long
    #define rep(i,s,e) for(int i=s;i<e;i++)
    #define repe(i,s,e) for(int i=s;i<=e;i++)
    #define CL(a,b) memset(a,b,sizeof(a))
    #define IN(s) freopen(s,"r",stdin)
    #define OUT(s) freopen(s,"w",stdout)
    const ll ll_INF = ((ull)(-1))>>1;
    const double EPS = 1e-8;
    const double pi = acos(-1.0);
    const int INF = 100000000;
    
    const int MAXN = 1e5+50;
    ll a[MAXN],ans[MAXN];
    const ll mi[20]={1,2,4,8,16,
                32,64,128,256,512,
                1024,2048,4096,8192,16384,
                32768,65536};
    
    ll n;
    void print()
    {
        ll out=0;
        out=ans[a[0]]^a[0];
        for(ll i=1;i<=n;i++)
            out+=ans[a[i]]^a[i];
        printf("%I64d
    ",out);
        printf("%I64d",ans[a[0]]);
    
        for(ll i=1;i<=n;i++)
            printf(" %I64d",ans[a[i]]);
        putchar('
    ');
    }
    
    
    int main()
    {
        //OUT("hdu5014.txt");
        //IN("hdu5014.txt");
        while(~scanf("%I64d",&n))
        {
            for(ll i=0;i<=n;i++)
                scanf("%I64d",&a[i]),ans[i]=i;
    
            //int id=lower_bound(mi,mi+17,n)-mi;  // id>=1  由于n>=1
            int id=16;
            while(mi[id]>n && id>=0)id--;
            if(id == 0) //说明n == 1
            {
                ans[0]=1;
                ans[1]=0;
                print();
                continue;
            }
            if(mi[id]>n)id--;
            ll cnt=0,last=0,ls=n;
            while(id>=0&& ls>=0)
            {
                ll k;
                for(k=0;mi[id]-k-1>=0 && k+mi[id]<=ls;k++)
                {
                    //printf("id=%d  mi[id]+k=%d mi[id]-k-1=%d
    ",id,mi[id]+k,mi[id]-k-1);
                    swap(ans[mi[id]+k],ans[mi[id]-k-1]);
                    //cnt+=2;
                    last=mi[id]-k-1;
                }
                ls=last-1;
                id--;
            }
            if(ans[0]==0 && ans[1]==1)swap(ans[0],ans[1]);
            print();
        }
        return 0;
    }
    


  • 相关阅读:
    利用 .NET Framework 命令行工具
    和AI机器人Alice的一段聊天记录
    WINDOWS自启动程序的10大隐身之所
    开放式开发/开源项目TimeDog[C#WindowsApp]
    Microsoft月度中文速递
    新安装的VS2003出现了一个问题不能新建项目!
    实例构造器和类型构造器的一些比较
    C++ 模板里面的typename
    vim 折叠的用法
    Redis3:持久化
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4554396.html
Copyright © 2011-2022 走看看