回 帖 发 新 帖 刷新版面

主题:第54次编程比赛

题目1(60分):对于一个自然数n,可以把它转换成对应的二进制数a[k] a[k-1] ..... a[1] a[0],其

中:n= ∑a[i] * 2^i 而且 a[i]=0 或1 (0=< i < k) , a[k]=1。如:10 转换为1010;5 转换为 101。

我们统计一下a[0]......a[k]这k+1 个数中的0 的个数和1 的个数。如果在这k+1 个数中,0 的个数比1 

个数多,就称n为A类数。给定m,求1~m (包含1,m)中A类数的个数。
函数接口:int solve(int m)
例如:m=3  return 0


题目2(40分):已知n∈Q,则2n+1∈Q,4n+5∈Q;且 1∈Q,求Q中第k小元素。
函数接口:int Q(int k)

判分要求:
1、结果正确得分,错误该题0分。
2、结果正确者,计分方法:该题用时最少者满分,其他按与满分者用时比计算。(例如,第一题最佳时

间1s,某人用时2s,则 1/2*60 = 30)
3、二题得分之和最大者胜出。


格式要求:所有代码包含在参赛者名字的名字空间中。例如:
//名字空间
namespace yxs0001
{
//以下为参赛代码
    int solve(int m)
    {
        return 0;
    }
    int Q(int k)
    {
        return 0;
    }
}




namespace yxs0001
{
    int solve(int m)
    {
        return 0;
    }
    
}
namespace yxs0001
{
    
    int Q(int k)
    {
        return 0;
    }
}

回复列表 (共34个回复)

11 楼

[code=c]
#include <cstdio>
#include <cassert>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

namespace iAkiak
{
    //&Ograve;&Ocirc;&Iuml;&Acirc;&Icirc;&ordf;&sup2;&Icirc;&Egrave;ü&acute;ú&Acirc;&euml;
    
    int gcd(int a, int b)
    {
        int t;
        if (a < b)
        {
            swap(a, b);
        }
        while(b > 0)
        {
            t = a % b;
            a = b;
            b = t;
        }
        return a;
    }
    // ×é&ordm;&Iuml;&Ecirc;&yacute;(m,n&sup2;&raquo;&sup3;&not;&sup1;&yacute;32)
    int c(int m, int n)
    {
        static int map[33][33];
        static bool inited = false;
        if (!inited)
        {
            inited = true;
            memset(map, 0xff, sizeof(map));
        }
        assert(m > 0 && m <= 32);
        assert(n >= 0 && n <= m);
        if (map[m][n] != -1)
            return map[m][n];
        
        int numerator = 1;
        int denominator = 1;
        while(n > 0)
        {
            numerator *= m, denominator *= n;
            int g = gcd(numerator, denominator);
            numerator /= g, denominator /= g;
            m--, n--;
        }
        assert(denominator == 1);
        return map[m][n] = numerator;
    }
    
    // n&Icirc;&raquo;&para;&thorn;&frac12;&oslash;&Ouml;&AElig;&Ecirc;&yacute;&pound;&not;0&micro;&Auml;&Ecirc;&yacute;&Aacute;&iquest;&sup2;&raquo;&ETH;&iexcl;&Oacute;&Uacute;a&micro;&Auml;&Aring;&Aring;&Aacute;&ETH;&Ecirc;&yacute;
    int count(int n, int a)
    {
        assert(n >= 0);
        if (n == 0)
            return a <= 0;
        if (a > n)
            return 0;
        int d = 0;
        for (int i = a; i <= n; i++)
            d += c(n,i);
        return d;
    }
    
    int solve(int m)
    {
        int sum = 0;
        int i, bitcount = 0;
        for (i = 1; (1<<i) <= m; i++)
        {
            sum += count(i - 1, i / 2 + 1);
        }
        //printf("debug %d\n", sum);
        bitcount = i--;
        m ^= 1 << i; // remove topbit
        int c0 = 0, c1 = 1;
        while(i >= 0)
        {
            for (i--; i >= 0 && (m & (1 << i)) == 0; i--)
                c0++;
            
            if (i >= 0)
            {
                assert(m & (1 << i));
                m ^= 1 << i;
                c1++;
                sum += count(i, bitcount / 2 + 1 - c0 - 1);
            }
        }
        if (c0 > c1)
            sum++;
        return sum;
    }
[/code]

12 楼

[code=c]
    int Q(int k)
    {
        assert(k > 0);
        if (k == 1)
            return 1;
        if (k > 2178308) // &Ograve;&ccedil;&sup3;&ouml;&pound;&not;&sup2;&raquo;&Euml;&atilde;&Aacute;&Euml;- -
            return 0;
        k--;
        
        vector<int> q;
        vector<int> newq;
        
        // &para;&Ocirc;32&Icirc;&raquo;int&cedil;&Otilde;&ordm;&Atilde;&sup1;&raquo;&Oacute;&Atilde;
        q.reserve(2178308);
        newq.reserve(78307);
        
        q.push_back(1);
        newq.push_back(1*2+1);
        newq.push_back(1*4+5);
        while(!newq.empty())
        {
            pop_heap(newq.begin(), newq.end(), greater<int>());
            int i = newq.back();
            if (i > q.back())
            {
                if (i < (INT_MAX - 5) / 4)
                {
                    newq.back() = i * 2 + 1;
                    push_heap(newq.begin(), newq.end(), greater<int>());
                    newq.push_back(i * 4 + 5);
                    push_heap(newq.begin(), newq.end(), greater<int>());
                    q.push_back(i);
                    if (--k == 0)
                        return i;
                }
                else if (i < (INT_MAX - 1) / 2)
                {
                    newq.back() = i * 2 + 1;
                    push_heap(newq.begin(), newq.end(), greater<int>());
                    q.push_back(i);
                    if (--k == 0)
                        return i;
                }
                else
                {
                    newq.pop_back();
                    q.push_back(i);
                    if (--k == 0)
                        return i;
                }
            }
            else
                newq.pop_back();
        }
        return 0;
    }
}
[/code]

13 楼

naspace xylgg
{
int Afrees(int n)
{
    int t;
    int fag=0;
    while(n>0)
    {
        t=n%2;
        n=n/2;
        if(t>0)
            fag++;
        else
            fag--;
    }
    return fag;        //fanghui bili.
}

int solve(int m)
{
    int t,x=0;
    for(int i=1;i<=m;i++)
    {
        t=Afrees(i);
        if(t<0)
        {
            std::cout<<i<<"  ";
            x++;
        }
    }
    return x;
}

int Q(int k)
{
    int a[256];
    a[0]=1;
    a[1]=3;
    int i=1;
    int j=2;
    while((i+1)<k)
    {
        a[j++]=2*a[i]+1;
        a[j++]=2*a[i]+3;
        i++;
    }
    return a[i];
}
}

14 楼

namespace leejqy
{
  int solve(int m)
{
  int A_no,one,zero,k,j,n;
   A_no=0;                      /*A类数个数赋初值*/
   for(n=1;n<=m;n++)
   {
      one=zero=0;            
      k=n;              
      j=1;
      while(k){
      if(k&1) 
        one++;          /*若为1则0NE+1,否则ZERO+1*/
        else zero++;
        k>>=j;
        j++;
        }
        if(zero>one)
         A_no++;
         }
         return A_no;
 }
}

15 楼

namespace maths_dxj
{

int Q(int k)
{
    int result = 3;
    if (k==1)
    {
        result = 1;
    }
    else
    {
        k+=-1;
        int F0=1;
        int F1=2;
        int sum=F0;
        int bit = 0;
        int temp,i;
        while(sum<k)
        {
            sum+=F1;
            temp = F1;
            F1 = F0 + F1;
            F0 = temp;
            bit++;
        }
        bool *flag = new bool[bit];
        k+=temp-sum-1;
        for(;k>0;)
        {
            F0=1;
            F1=2;
            sum=F0;
            i = 0;
            while(F1<=k)
            {
                sum+=F1;
                temp = F1;
                F1 = F0 + F1;
                F0 = temp;
                i++;
            }
            k-=temp;
            flag[i]=1;
        }
        for(int j=bit-1;j>=0;j--)
        {
        
            if (flag[j]==1)
            {
                result =(result<<1)+3;
            }
            else
            {
                result =(result<<1)+1;
            }
        }
        delete[] flag;
    }
        return result;
}
int solve(int m)
{
    int *store = new int[m+1];//用于存储可能满足条件的数
    store[0] = 1;
    int *cnt = new int[m+1];//用于记录上述存储的数种1、0个数差
    int *bb = new int[m+1];
    cnt[0] = -1;
    int result=0,temp=1;
    int i = 0,t,a,cc=0,bit=0,Ct=0;
    while(temp<=m)
    {
        temp=(temp<<1);
        bit++;
    }//求m的位数
    bb[0]=1;
    while(1)
    {        
        t=cc;
        a=store[cc++];

        store[++i] = a<<1;
        if(store[i]>m)break;
        cnt[i]=cnt[t]+1;
        bb[i]=bb[t]+1;
        if(cnt[i]>=1)
        {
        result++;
        }                
        if(cnt[t]+bit-bb[t]>2)
        {
            store[++i] = (a<<1)+1;
            if(store[i]>m)break;
            cnt[i]=cnt[t]-1;
            bb[i]=bb[t]+1;
            if(cnt[i]>=1)
            {
            result++;
            }            
        }
    }

    delete[] store;
    delete[] cnt;
    delete[] bb;

    return result;
}

}

16 楼

namespace leejqy{
int solve(int m)
{
  int A_no,one,zero,k,j,n;
   A_no=0;
   for(n=1;n<=m;n++)
   {
      one=zero=0;
      k=n;
      j=1;
      while(k){
      if(k&1)
        one++;
        else zero++;
        k>>=j;
        j++;
        }
        if(zero>one)
         A_no++;
         }
         return A_no;
}
}

17 楼


[code=c]
namespace pysn
{
    int count=0;
    for(int i=1;i<m+1;i++)
    {
            int numOfB1=0,numOfB0=0;
            int one=1,forward0=0;
            do
            {
                if(one&i) 
                {
                   numOfB1++;
                   forward0=0;
                }
                else 
                {
                   numOfB0++;
                   forward0++;
                }
                one<<=1;               
            }while(one);
            if(numOfB0-forward0>numOfB1) count++;
    }
    return count;    
}
[/code]

//第二道想不出什么效率高的算法,用数组有溢出,就不做了。

18 楼

//第二题
namespace 小黑骑DK
{    
    #include <string.h>
    #include <stdlib.h>
    int get_add(int plane,int count);
    int get_plane(int k, int *sum);
    int Q(int k);
    
    int Q(int k)//没做参数检查,假定k是大于0的
    {
        if (k < 3)
        {
            return (k==1) ? 1 : 3;
        }
        else
        {
            int count = 0;
            int plane = get_plane(k,&count);
            int addNum = get_add(plane, count);        
            int multi = 1<<plane;//n前面的系数

            return (multi + addNum);//如果n!=1,则multi*n + addNum.
        }
    }

    int get_plane(int k, int *count)//计算第k个元素在第几层.层数即为n前面的系数
    {
        static const int f[32] = {1,2,4,7,12,20,33,54,88,143,232,376,609,986,1596,
                                  2583,4180,6764,10945,17710,28656,46367,75024,
                                  121392,196417,317810,514228,832039,1346268,2178308,
                                  3524577,5702886};//菲波那切数列.f[k]也是第k层前元素总和
        int plane = 1;

        for (; f[plane]<k; plane++)
            ;
        
        *count = k - f[plane-1];
        return plane;
    }

    int get_add(int plane,int count)//获得加数部分
    {
        static const int f[32] = {1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,
                                  2584,4181,6765,10946,17711,28657,46368,75025,
                                  121393,196418,317811,514229,832040,1346269,2178309};
        int *pAddPart = (int *)malloc(sizeof(int) * f[plane]);//plane层所有元素的加数
        int i = 1;
        int missCount = 1;//有些元素不能加3. 记录不能加3的元素个数
        int path[32] = {0};//plane层第count个元素的加数
        int pathEnd = 0;
        int addNum = 1;//第1层加数为1. 2*n + 1
        int planeTemp = plane - 1;

        //4A(n-2)+5=2A(n-1)+3 = A(n).2A(n-1)+1 = A(n)
        *pAddPart = 1, *(pAddPart+1) = 3;//第2层的系数
        for (; i+1<plane; i++)
        {
            memcpy(pAddPart+f[i+1], pAddPart, sizeof(int)*f[i]);
        }

        while (pathEnd < planeTemp)
        {
            path[pathEnd++] = pAddPart[count-1];
            for (; count<f[plane-1]; plane--)
                ;
            if (plane > 2)//求plane层上一层的3数
            {
                missCount = f[plane-3];
            }
            else//第二层以上(即0和1层)没有3
            {
                missCount = 0;
            }
            for (i=f[plane-1]; i<count; i++)
            {
                if (pAddPart[i] == 3)
                {
                    missCount++;
                }
            }
            count -= missCount;
        }

        for (i=pathEnd-1; i>=0; i--)
        {
            addNum = 2*addNum + path[i];
        }
        
        free(pAddPart);
        return addNum;
    }
}

19 楼

//第一题
namespace 小黑骑DK
{
    int is_A(int num);
    int solve(int m);

    int solve(int m)
    {
        int count = 0;
        int i;

        for (i=4; i<=m; i++)
        {
            if (is_A(i))
            {
                count++;
            }
        }

        return count;
    }

    int is_A(int num)
    {
        int twoNum = 1;//表示num所需要的二进制位数
        int oneNum = 0;//1的个数
        int numTemp = num;
        int i;

        for (; num/=2; twoNum++)
            ;
        for (i=0; i<twoNum; numTemp>>=1,i++)
        {
            if (numTemp & 1)
            {
                oneNum++;
            }
        }

        if (oneNum < twoNum-oneNum)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

20 楼

头文件:include <math.h>
只用里面的log2函数,如果没有,请用其他求以2为底的对数的函数代替
namespace wangfangbob
{
    int solve( int m )
    {
        static int base [30][15] = { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 4, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 5, 11, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 6, 16, 26, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 7, 22, 42, 57, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 8, 29, 64, 99, 120, 127, 128, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 9, 37, 93, 163, 219, 247, 255, 256, 0, 0, 0, 0, 0, 0 },
            { 1, 10, 46, 130, 256, 382, 466, 502, 511, 512, 0, 0, 0, 0, 0 },
            { 1, 11, 56, 176, 386, 638, 848, 968, 1013, 1023, 1024, 0, 0, 0, 0 },
            { 1, 12, 67, 232, 562, 1024, 1486, 1816, 1981, 2036, 2047, 2048, 0, 0, 0 },
            { 1, 13, 79, 299, 794, 1586, 2510, 3302, 3797, 4017, 4083, 4095, 4096, 0, 0 },
            { 1, 14, 92, 378, 1093, 2380, 4096, 5812, 7099, 7814, 8100, 8178, 8191, 8192, 0 },
            { 1, 15, 106, 470, 1471, 3473, 6476, 9908, 12911, 14913, 15914, 16278, 16369, 16383, 16384 },
            { 1, 16, 121, 576, 1941, 4944, 9949, 16384, 22819, 27824, 30827, 32192, 32647, 32752, 32767 },
            { 1, 17, 137, 697, 2517, 6885, 14893, 26333, 39203, 50643, 58651, 63019, 64839, 65399, 65519 },
            { 1, 18, 154, 834, 3214, 9402, 21778, 41226, 65536, 89846, 109294, 121670, 127858, 130238, 130918 },
            { 1, 19, 172, 988, 4048, 12616, 31180, 63004, 106762, 155382, 199140, 230964, 249528, 258096, 261156 },
            { 1, 20, 191, 1160, 5036, 16664, 43796, 94184, 169766, 262144, 354522, 430104, 480492, 507624, 519252 },
            { 1, 21, 211, 1351, 6196, 21700, 60460, 137980, 263950, 431910, 616666, 784626, 910596, 988116, 1026876 },
            { 1, 22, 232, 1562, 7547, 27896, 82160, 198440, 401930, 695860, 1048576, 1401292, 1695222, 1898712, 2014992 },
            { 1, 23, 254, 1794, 9109, 35443, 110056, 280600, 600370, 1097790, 1744436, 2449868, 3096514, 3593934, 3913704 },
            { 1, 24, 277, 2048, 10903, 44552, 145499, 390656, 880970, 1698160, 2842226, 4194304, 5546382, 6690448, 7507638 },
            { 1, 25, 301, 2325, 12951, 55455, 190051, 536155, 1271626, 2579130, 4540386, 7036530, 9740686, 12236830, 14198086 },
            { 1, 26, 326, 2626, 15276, 68406, 245506, 726206, 1807781, 3850756, 7119516, 11576916, 16777216, 21977516, 26434916 },
            { 1, 27, 352, 2952, 17902, 83682, 313912, 971712, 2533987, 5658537, 10970272, 18696432, 28354132, 38754732, 48412432 },
            { 1, 28, 379, 3304, 20854, 101584, 397594, 1285624, 3505699, 8192524, 16628809, 29666704, 47050564, 67108864, 87167164 },
            { 1, 29, 407, 3683, 24158, 122438, 499178, 1683218, 4791323, 11698223, 24821333, 46295513, 76717268, 114159428, 154276028 },
            { 1, 30, 436, 4090, 27841, 146596, 621616, 2182396, 6474541, 16489546, 36519556, 71116846, 123012781, 190876696, 268435456 } };

我来回复

您尚未登录,请登录后再回复。点此登录或注册