回 帖 发 新 帖 刷新版面

主题:第43次编程比赛第一题题目

PROBLEM:
N个1和N个0组成一个2N位的二进制数,要求从左到右扫描,1的累计数不小于0的累计数,试求满足这种条件的数的个数P

INPUT:
输入文件为:DATA1.IN
内有[color=FF0000]一个[/color]整数N(N<=100)

OUTPUT
输出文件为:ANS1.OUT
输出一个数P,P精确到个位,即输出所有数位

SAMPLE INPUT
3

SAMPLE OUTPUT
5

解释:
例如N=3时,P=5,为
111000
110100
110010
101010
101100

HINT:不要想复杂了[em2]

回复列表 (共19个回复)

沙发

test

板凳

有没有答案啊!

3 楼


n

4 楼

#include <stdio.h>

#define true 1
#define MAX 100

char data[MAX], n;

void next();
char comp();

int main()
{
    int i, resu = 0, count = 0;

    FILE *pf_in = NULL;
    FILE *pf_out = NULL;

    pf_in = fopen("DATA1.IN","r");
    pf_out = fopen("ANS1.OUT","w");

    if (pf_in == NULL || pf_out == NULL)
    {
        printf("打开文件失败!");
        return 0;
    }

    fscanf(pf_in,"%d",&n);    
    
    for (i=n*2-1; i>=0; i--)
    {
        data[i] = i%2;    /*高高低低存取*/
    }
    count++;

    while (true) 
    {
        next();
        resu = comp();
        
        if (resu == 0) 
            continue;
        if (resu == 1)
        {
            count++;
            continue;
        }
        if (resu == 2)
        {
            count++;
            break;
        }
        
    }

    fprintf(pf_out,"%d",count);

    fclose(pf_in);
    fclose(pf_out);
    return 0;
}
void next() 
{
    int i = 0, j = 1, f_con = 0;
    while (i < n * 2)
    {
        if (data[i] == 1) break;        
        i++;
    }
    
    while (i < n * 2)
    {
        if (data[i] == 1)
        {
            data[i] = 0;
            f_con++;
        }
        else 
        {
            data[i] = 1;
            f_con--;
            break;
        }
        i++;
    }
    
    while (f_con > 0)
    {
        data[j] = 1;
        j += 2;
        f_con--;
    }    
}

char comp()
{
    int con_i = 0, con_j = 0, k = 2 * n - 1;
    while (k>=0)
    {
        data[k] ? con_i++ : con_j++;
        if (con_i < con_j)
            return 0;
        if (con_i == n && con_j == 0)
            return 2;
        k--;
    }
    return 1;
}

5 楼

大大款土土土土土土土土

6 楼


[em20][em19][em16][em12][em9][em13][em15][em19][em6][em5][em2][em1][em10][em13][em14][em16][em16][em18]

7 楼


[em20][em19][em16][em12][em9][em13][em15][em19][em6][em5][em2][em1][em10][em13][em14][em16][em16][em18]

8 楼

#include <cassert>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

template<typename T, T Base>
struct BigUInt
{
    typedef vector<T> data_type;
    vector<T> data;
    bool bValid;
    BigUInt() : bValid(false)
    {
    }
    BigUInt(T n)
    {
        *this = n; 
    }
    BigUInt operator + (const BigUInt &o) const
    {
        assert(Base * 3 < UINT_MAX);
        BigUInt a;
        size_t i, len = min(data.size(), o.data.size());
        T carry = 0, t;
        a.data.reserve(max(data.size(), o.data.size()));
        for (i = 0; i < len; i++)
        {
            t = data[i] + o.data[i] + carry;
            a.data.push_back(t % Base);
            carry = t / Base;
        }
        for (; i < data.size(); i++)
        {
            t = data[i] + carry;
            a.data.push_back(t % Base);
            carry = t / Base;
        }
        for (; i < o.data.size(); i++)
        {
            t = o.data[i] + carry;
            a.data.push_back(t % Base);
            carry = t / Base;
        }
        if (carry)
            a.data.push_back(carry);
        a.bValid = true;
        return a;
    }
    BigUInt& operator = (T n)
    {
        data.clear();
        while(n >= Base)
        {
            data.push_back(n);
            n /= Base;
        }
        data.push_back(n);
        bValid = true;
        return *this;
    }
    bool valid() const
    {
        return bValid;
    }
};
typedef BigUInt<unsigned long, 100000000> Number;
Number gCount[101][101];

void println(const Number &o)
{
    if (!o.valid() || o.data.empty())
        printf("0\n");
    else
    {
        Number::data_type::const_reverse_iterator t = o.data.rbegin();
        printf("%d", *t++);
        while(t != o.data.rend())
        {
            printf("%08d", *t++);
        }
        printf("\n");
    }
}
const Number& t(int n1, int n0)
{
    int former1 = n0 - n1;
    if (former1 < 0 || n0 < 0 || n1 < 0)
        return gCount[0][0];
    if (!gCount[n1][n0].valid())
        gCount[n1][n0] = t(n1-1, n0) + t(n1, n0-1);
    return gCount[n1][n0];
}

const Number& f(int n)
{
    gCount[0][0] = 0;
    gCount[0][1] = 1;
    return t(n, n);
}

int main()
{
    int n;
    freopen("DATA1.IN", "r", stdin);
    freopen("ANS1.OUT", "w", stdout);

    while(scanf("%d", &n) == 1)
    {
        println(f(n));
    }
    return 0;
}


9 楼

//结果为(2N)!/((N)!(N+1)!) 
//即(N+2)*(N+3)*(N+4)...(2N-1)*2N/ (2*3*4*5...(N-1)*N)

#include <fstream>
#include <memory.h>

using namespace std;

int maxgys(int a,int b)
{
    int c=a%b;
    if(c==0)
        return b;
    else
        return maxgys(b,c);
}

void yuefen(int *a,int *b)
{
     int c=maxgys(*a,*b);
     *a/=c;
     *b/=c;
}

int main()
{
    int N,*Result,used=0;
    int i,j,t;
    char temp[]="0000";
    ifstream in("DATA1.IN");
    ofstream out("ANS1.OUT");
    in>>N;
    int *N1=new int[N-1];
    int *N2=new int[N-1];
    Result=new int[2500];       //可以设有2500*4=10000位数字,N=2000,才597位数字
    memset(Result,0,2000*sizeof(int));
    Result[0]=1;
    for(i=0;i<N-1;i++)
    {
        N1[i]=N+2+i;
        N2[i]=2+i;
    }
    for(i=0;i<=N-2;i++)
    {
        for(j=N-2;j>=0;j--)
        {
            yuefen(&N1[j],&N2[i]);
            if(N2[i]==1) break;  //一定能把全部的N2[i]约成1,否则,结果不是整数
        }
    }
    for(i=0;i<=N-2;i++)
    {
        t=0;
        for(j=0;j<=used;j++)
        {
            Result[j]*=N1[i];
            Result[j]+=t;
            if(Result[j]>=10000)
            {
                t=Result[j]/10000;
                Result[j]%=10000;
                if(j==used) used++;
            }
        }
    }
    out<<Result[used];
    for(i=used-1;i>=0;i--)
    {
        t=Result[i];
        temp[0]='0'+t/1000;
        temp[1]='0'+(t%1000)/100;
        temp[2]='0'+(t%100)/10;
        temp[3]='0'+(t%10);
        out<<temp;
    }
    return 0;
}

10 楼

#include <fstream>
#include <iostream>

using namespace std;

const char * input="DATA1.IN";
const char * output="ANS1.OUT";

long long m[101][201];

//r: number of 1 left, n: digits left
long long find_ans(int r, int n)
{
    if(m[r][n]>=0) return m[r][n];
    m[r][n]=find_ans(r-1,n-1)+find_ans(r,n-1);
    return m[r][n];
}
int main()
{
    ifstream fin(input);
    ofstream fout(output);
    for(int n=0;n<=200;n++)
    {
        for(int r=0;r<=100;r++)
        {
            if(n<2*r) m[r][n]=0;
            else if(r==0&&n!=0) m[r][n]=1;
            else if(n==0) m[r][n]=0;
            else m[r][n]=-1;
        }
    }
    int n;
    fin>>n;
    fout<<find_ans(n,2*n)<<endl;
    return 0;
}

我来回复

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