题意

   我过的是比较幸运的。首先我用一个二维数组f[][]存下某些状态,其中f[i][j]表示长度为i,1的个数不超过j的数目。然后如果某个数小于2^L,那么肯定输出原数,如果不是再特殊处理,找到第一个f[i][L]比I大的i。然后比较I和f[i][L],f[i-1][L]其中哪个近,离哪个近就从那边开始搜。一直搜到结果为止,这样能过,但是险过。有一组数据用时0.9+S。其中还有一些要注意的就是用long long。也就是如果测试数据有31 31的话,不用long long 会超数据范围。(我大致算了下,我这种写法,极限数据应该会超过1S,那样的话必挂无疑。但是好像usaco的数据没这种)

   官方的:首先也是处理一个和我的一样的二维数组。不过后面明显比我的要好,标称是用递归写的,直接输出。

void printbits(int nbits, int nones, double index)

   {/*nbits 表示剩下的要处理的长度  nones 表示剩下的1的个数  index表示第多少个*/     

       double s;     

       if(nbits == 0)/*处理完成*/

           return;     

       s = sizeofset[nbits-1][nones];/*得到f[bits-1][nones]*/

       if(s <= index) 

        {/*如果index大于这个f值*/

          fprintf(fout, "1");/*那么这位肯定是1 */       

           printbits(nbits-1, nones-1, index-s);/*改变相应的状态 继续输出  长度-1,1的个数-1 index-s 这里这个index-s有点像10进制化2进制*/   

        } 

      else

        {  

          fprintf(fout, "0"); /*小于这个f值这位肯定为0*/ 

          printbits(nbits-1, nones, index);/*改变相应的状态继续输出  长度-1 1的个数不减 index也不变*/

        }

   }

还是修炼不够啊。。。。