题意
我过的是比较幸运的。首先我用一个二维数组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也不变*/
}
}
还是修炼不够啊。。。。