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 < 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 ;
}