ZOJ 3457 Absence Number【数学题,打表】


http://watashi.ws/blog/1813/zojmonthly1101/ZOJ3457/
ZOJ 3457 Absence Number

大意:

给定一个两位数N,求最小的m,使得1/m的十进制表示中恰好包含除N以外的所有两位数。

最大的解是N=0时m=76344。题目的输入只有100种,所以可以暴力跑表,1/m十进制表示是循环小数,且在m步内开始循环,所以很容易求得其包含的所有两位数,最后判断一下是否满足条件就好了。注意不要漏数了两个循环节头尾组成的那个两位数,否则有几个数据会WA。更简单的方法是不判断循环节,直接循环m+1步。加上一些优化后,这个表实际可以在1s之内跑出。


但是我不会~~~~(>_<)~~~~ 我的打表要20秒。。。只能邪恶一下下了。。。

#include < stdio.h >
#include
< string .h >
const int N = 101 ;
const int M = 500005 ;
int ans[] = { 76344 , 27839 , 2938 , 5246 , 8662 , 13161 , 7412 , 7843 , 3386 , 4566 , 8596 ,
981 , 1654 , 5609 , 2623 , 11357 , 5703 , 13634 , 1269 , 7067 , 10146 ,
7748 , 1017 , 2006 , 13987 , 2737 , 1007 , 9269 , 2191 , 9633 , 5637 ,
17406 , 4746 , 327 , 19798 , 10219 , 6902 , 11815 , 7869 , 731 , 5972 ,
5473 , 8849 , 9822 , 3222 , 16274 , 2751 , 22414 , 2183 , 5974 , 7573 ,
5391 , 6837 , 8762 , 7747 , 1962 , 5629 , 9691 , 10158 , 1493 , 1462 ,
15796 , 3594 , 8109 , 2359 , 14382 , 339 , 6873 , 19194 , 10262 , 5459 ,
5163 , 20049 , 4028 , 3113 , 27279 , 1003 , 3924 , 1937 , 2679 , 5183 ,
3378 , 2969 , 21395 , 13907 , 3074 , 4911 , 827 , 6471 , 4279 , 2283 ,
8465 , 2538 , 527 , 17751 , 7526 , 9422 , 7345 , 5083 , 791 };
bool visited[N]; // 存储该数字是否出现过
bool lef[M]; // 存储该余数是否被访问
int get ( int n)
{
memset(visited,
false , sizeof (visited));
memset(lef,
false , sizeof (lef));
int pre;
int left = 1 ;
while (left * 10 < n)left *= 10 ;
pre
= 0 ;
int vnum = 0 ;
int tn = n;
while (tn -- )
{
left
= left * 10 ;
int curans = pre * 10 + left / n;
if (visited[curans] == false )
{
visited[curans]
= true ;
vnum
++ ;
}

left
= left % n;
if (lef[left] == true )
{
pre
= curans % 10 ;
left
= left * 10 ;
curans
= pre * 10 + left / n;
if (visited[curans] == false )
{
visited[curans]
= true ;
vnum
++ ;
}
break ;

}
lef[left]
= true ;
pre
= curans % 10 ;
}

if (vnum == 99 )
{
int i;
for (i = 0 ;i < 100 ;i ++ )
if (visited[i] == false ) return i;
}
return - 1 ;
}
void init()
{
memset(ans,
- 1 , sizeof (ans));
int i,j,k;
int find = 0 ;
for (i = 100 ;;i ++ )
{
int temp = get (i);
if (temp !=- 1 && ans[temp] ==- 1 )
{
ans[temp]
= i;
find
++ ;
// printf("ans[%d]=%d\n",temp,i);
if (find == 100 ) break ;
}
}

printf(
" ans[] = {%d, " ,ans[ 0 ]);
for (i = 1 ;i < 99 ;i ++ )
{
printf(
" %d, " ,ans[i]);
if (i % 10 == 0 )printf( " \n " );
}
printf(
" %d}; " ,ans[ 99 ]);

}
int main()
{

// init();

int n;
while (scanf( " %d " , & n) != EOF)
printf(
" %d\n " ,ans[n]);
return 0 ;
}

你可能感兴趣的:(number)