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\n",out);
    printf("%I64d",ans[a[0]]);

    for(ll i=1;i<=n;i++)
        printf(" %I64d",ans[a[i]]);
    putchar('\n');
}

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\n",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;
}
时间: 2024-10-02 09:28:07

hdu 5014 思维题/推理的相关文章

hdu 4883 思维题

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4883 TIANKENG’s restaurant Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 566    Accepted Submission(s): 267 Problem Description TIANKENG manages a

hdu 4810 思维题+二进制位规律+异或规律 213南京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4810 以前做过一些涉及异或的题,化为二进制形式,然后统计0,1个数是一种很常见的处理方法,但是在做这个题的时候居然没尝试,脑残啊...... 一开始看5s时限,感觉稍微暴力一点应该可以,于是YY的O(n^3)算法但是没去实现,明显超时啊,大致就是通过C(n,1)的组合可以在O(n^2)内处理出C(n,2)的组合,在通过C(n,2)处理出C(n,3)的组合....但是C(n,2)已经是n^2个数了,所以算法是O

Just Random HDU - 4790 思维题(打表找规律)分段求解

Coach Pang and Uncle Yang both love numbers. Every morning they play a game with number together. In each game the following will be done:  1. Coach Pang randomly choose a integer x in [a, b] with equal probability.  2. Uncle Yang randomly choose a i

朋友HDU - 5963 (思维题) 三种方法

传送门 题目描述 输入 输出 样例输入 2 2 3 1 2 0 0 1 1 2 1 1 0 2 4 11 1 2 1 2 3 1 3 4 0 0 1 0 2 0 3 0 4 1 2 1 0 0 1 0 2 0 3 1 3 4 1 0 3 0 4 Sample Input 样例输出 Boys win! Girls win! Girls win! Boys win! Girls win! Boys win! Boys win! Girls win! Girls win! Boys win! Girl

hdu 5491 思维题

#include<stdio.h> #include <math.h> #include <algorithm> #include <math.h> #include <string.h> #include <bitset> #include <iostream> using namespace std; #define LL long long void out(LL x) { bitset<32>s(x);

Fang Fang HDU - 5455 (思维题)

Fang Fang says she wants to be remembered. I promise her. We define the sequence FF of strings. F0 = ''f",F0 = ''f", F1 = ''ff",F1 = ''ff", F2 = ''cff",F2 = ''cff", Fn = Fn?1 + ''f", for n > 2Fn = Fn?1 + ''f", fo

hdu 4972 A simple dynamic programming problem (转化 乱搞 思维题) 2014多校10

题目链接 题意:给定一个数组记录两队之间分差,只记分差,不记谁高谁低,问最终有多少种比分的可能性 分析: 类似cf的题目,比赛的时候都没想出来,简直笨到极点..... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <vector> 7 #include &

hdu 4932 /bestcoder B题 #4 /思维题

题意:给一个数列(整数),用一些不相交的区间去覆盖(只能是用端点去覆盖,端点可以交).而且区间出度相等.求最大区间长度. 开始一下就敲了,枚举每个区间长度,判断合法,更新最大.但是后来一看小数,感觉不行,改为二分,后来还是挂了... 赛后才知道,二分的时候,答案必需要满足单调性啊,这里小的数据不行,大的数据可以行!如 0 1 5 6 10, 3不行,4行. 后来才知道,枚举时,每个差值的一半也是可以的:仔细想想很容易证明.(水,坑) #include<iostream> #include<

HDU 5014 Number Sequence(西安网络赛H题)

HDU 5014 Number Sequence 题目链接 思路:对于0-n,尽量不让二进制中的1互相消掉就是最优的,那么只要两个数只要互补就可以了,这样每次从最大的数字,可以找到和他互补的数字,然后这个区间就能确定了,然后剩下的递归下去为一个子问题去解决 代码: #include <cstdio> #include <cstring> const int N = 100005; int n, a[N], ans[N]; int cnt[N]; int count(int x) {