现在的位置: 首页 > 综合 > 正文

算法练习 – Stringsobits

2014年01月26日 ⁄ 综合 ⁄ 共 4936字 ⁄ 字号 评论关闭
文章目录

思路:

1. 首先获取总共n bit,有不多于i个1的字串的集合数目。这是个DP问题。f( n,i )表示共n bit,不多于i个1 的字串集合数目,则:

字串的最高位可能是0,也可能是1,是0的话,剩余的 n-1 bit可以使用不多于i个1,f(n-1,i )。

最高位是1的话,剩下的n-1 bit可以使用不多于 i-1 个1,f( n-1, i-1 )。

f( n, i ) = f( n-1, i ) + f( n-1, i-1 )

2. 题目要求获取指定第几个。

从最高位开始考虑,因为最高位的权值最高,所以最高位为0时所有的字串一定小于最高位为1时的字串。

最高位为0时满足要求的字串集合数目如果大于或等于题目指定要求的序号,那说明最高位是0。

如果最高位为0时满足要求的字串集合数目小于题目有要求的序号,那说明最高位是1,要求序号减去最高位是0时的数目。

循环一下,就能得到题目要求的字串。

题目:

Stringsobits
Kim Schrijvers

Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either 0 or 1.

This set of strings is interesting because it is ordered and contains all possible strings of length N that have L (1 <= L <= N) or fewer bits that are `1'.

Your task is to read a number I (1 <= I <= sizeof(S)) from the input and print the Ith element of the ordered set for N bits with no more than L bits that are `1'.

PROGRAM NAME: kimbits

INPUT FORMAT

A single line with three space separated integers: N, L, and I.

SAMPLE INPUT (file kimbits.in)

5 3 19

OUTPUT FORMAT

A single line containing the integer that represents the Ith element from the order set, as described.

SAMPLE OUTPUT (file kimbits.out)

10011

代码:

/*

ID: thinkin6

PROG: kimbits

LANG: C++

*/

 

/** USA CO 3.2.2 :

Stringsobits

Kim Schrijvers

Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either 0 or 1.

 

This set of strings is interesting because it is ordered and contains all possible strings of length N that have L (1 <= L <= N) or fewer bits that are `1'.

 

Your task is to read a number I (1 <= I <= sizeof(S)) from the input and print the Ith element of the ordered set for N bits with no more than L bits that are `1'.

 

PROGRAM NAME: kimbits

 

INPUT FORMAT

 

A single line with three space separated integers: N, L, and I.

SAMPLE INPUT (file kimbits.in)

 

5 3 19

OUTPUT FORMAT

 

A single line containing the integer that represents the Ith element from the order set, as described.

SAMPLE OUTPUT (file kimbits.out)

 

10011

 

 

*/

 

/** 

思路:

* 实现大数乘法.

*/

#include <stdio.h>

#include <stdlib.h>

#include <iostream>

#include <fstream>

#include <string>

#include <map>

#include <vector>

#include <list>

#include <math.h>

#include <set>

#include <sstream>

#include <algorithm>

#include <memory.h>

#include <complex>

#include <queue>

 

#ifdef _WIN32

#include <time.h>

#endif

 

using namespace std;

 

#ifdef _WIN32

typedef __int64 n64;

typedef unsigned __int64 u64;

#else

typedef long long n64;

typedef unsigned long long u64;

#endif

typedef unsigned long u32;

 

#ifdef _WIN32

#define THINKINGL 1

#endif

 

/** 获取nTotalBits长度下,不多于nMax1Num个1时可以组成的组合数目. 

*/

u32 GetCount( int nMax1Num, int nTotalBits )

{

// 判断结束条件.

if ( nMax1Num == 0 )

{

return 1;

}

if ( nTotalBits == 0 )

{

return 1;

}

 

u32 nCount = 0;

// 最高位0

nCount += GetCount( nMax1Num, nTotalBits - 1 );

// 最高位1

nCount += GetCount( nMax1Num-1, nTotalBits-1 );

return nCount;

}

 

/** 循环的方式得到结果. */

u32 GetCountFast( int nMax1Num, int nTotalBits )

{

const int MAX_1_NUM = 32;

const int MAX_TOTAL_BITS = 32;

static u32 s_arCount[MAX_1_NUM][MAX_TOTAL_BITS];

static bool s_bInited = false;

 

if ( !s_bInited )

{

memset( s_arCount, 0, sizeof( s_arCount ) );

s_bInited = true;

 

// 初始化数组.

for ( int i=0; i<MAX_1_NUM; ++i )

{

s_arCount[i][0] = 1;

}

for ( int i=0; i<MAX_TOTAL_BITS; ++i )

{

s_arCount[0][i] = 1;

}

 

// 循环获取.

// f( nMax1Num, nTotalBits ) = f( nMax1Num, nTotalBits-1 ) + f( nMax1Num-1, nTotalBits-1 )

for ( int i=1; i<MAX_TOTAL_BITS; ++i )

{

for ( int k=1; k<=MAX_1_NUM; ++k )

{

if ( k>i )

{

s_arCount[k][i] = s_arCount[i][i];

}

else

{

s_arCount[k][i] = s_arCount[k][i-1] + s_arCount[k-1][i-1];

}

}

}

}

 

return s_arCount[nMax1Num][nTotalBits];

}

 

int main()

{

string strProblemName = "kimbits";

string strInFile = strProblemName + ".in";

string strOutFile = strProblemName + ".out";

ofstream fout ( strOutFile.c_str() );

ifstream fin ( strInFile.c_str() );

 

if( !fin )

{

cout << "open input file fail!" << endl;

return 0;

}

 

int nBitsNum, nMax1Num, nIndex;

fin >> nBitsNum >> nMax1Num >> nIndex;

 

stringstream ssTargetNum;

for ( int i=nBitsNum; i>0; --i )

{

if ( GetCountFast( nMax1Num, nBitsNum-1 ) >= nIndex )

{

// 最高位0.可以满足数目要求.

ssTargetNum << '0';

}

else

{

// 最高位1,去掉0时的组合.

ssTargetNum << '1';

nIndex -= GetCountFast( nMax1Num, nBitsNum-1 );

nMax1Num --; // 最高位占用一个1.

}

 

// 去掉最高位.

nBitsNum --;

}

 

cout << ssTargetNum.str() << endl;

fout << ssTargetNum.str() << endl;

 

fin.close();

fout.close();

 

#ifdef THINKINGL

 

cout << "use clock: " << clock() << " / " << CLOCKS_PER_SEC << endl;

 

cout << "-----------begin--dump--output--file----------------" << endl << endl;

system( ( string( "type " ) + strOutFile ).c_str() );

cout << endl;

system( "pause" );

#endif

 

return 0;

}

结果:

USER: Zinsser Lee [thinkin6]
TASK: kimbits
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.022 secs, 2944 KB]
   Test 2: TEST OK [0.011 secs, 2944 KB]
   Test 3: TEST OK [0.011 secs, 2944 KB]
   Test 4: TEST OK [0.011 secs, 2944 KB]
   Test 5: TEST OK [0.000 secs, 2944 KB]
   Test 6: TEST OK [0.011 secs, 2944 KB]
   Test 7: TEST OK [0.000 secs, 2944 KB]
   Test 8: TEST OK [0.011 secs, 2944 KB]
   Test 9: TEST OK [0.011 secs, 2944 KB]
   Test 10: TEST OK [0.011 secs, 2944 KB]
   Test 11: TEST OK [0.000 secs, 2944 KB]
   Test 12: TEST OK [0.011 secs, 2944 KB]
   Test 13: TEST OK [0.000 secs, 2944 KB]

All tests OK.

YOUR PROGRAM ('kimbits') WORKED FIRST TIME! That's fantastic -- and a rare thing. Please accept these special automated congratulations.

Here are the test data inputs:

------- test 1 -------
4 2 1
------- test 2 -------
1 1 2
------- test 3 -------
8 4 30
------- test 4 -------
10 2 56
------- test 5 -------
7 7 64
------- test 6 -------
18 3 300
------- test 7 -------
21 10 1048576
------- test 8 -------
24 20 12936478
------- test 9 -------
31 24 10000000
------- test 10 -------
31 31 2147483648
------- test 11 -------
31 26 12345678
------- test 12 -------
31 26 123456789
------- test 13 -------
31 26 1234567890

Keep up the good work!

Thanks for your submission!

【上篇】
【下篇】

抱歉!评论已关闭.