题目分析:我们很容易想到打表这个不用脑的方法。不过!sgu就是不给你内存,怎么着!
于是我们另辟蹊径,发现增量最多6*9+1,所以我们只用开一个比这个稍微大一点的数组,然后类似滚动数组的方法使用就好了!
将询问保存在结构体中,答案就在推的过程顺便得到。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
//#include <cmath>
#include <queue>
using namespace std ;
typedef long long LL ;
#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define rev( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define clr( a , x ) memset ( a , x , sizeof a )
#define cpy( a , x ) memcpy ( a , x , sizeof a )
struct Node {
int idx , kth ;
bool operator < ( const Node& a ) const {
return kth < a.kth ;
}
} ;
bool a[64] ;
int num[10005] ;
Node node[5005] ;
int ans[5005] ;
int n , k ;
void preprocess () {
For ( i , 1 , 10000 ) {
num[i] = 0 ;
int x = i ;
while ( x ) {
num[i] += x % 10 ;
x /= 10 ;
}
}
}
void solve () {
int cnt = 0 , cur = 1 ;
clr ( a , 0 ) ;
preprocess () ;
For ( i , 1 , k ) {
scanf ( "%d" , &node[i].kth ) ;
node[i].idx = i ;
}
sort ( node + 1 , node + k + 1 ) ;
For ( i , 1 , n ) {
if ( !a[i & 63] ) {
++ cnt ;
while ( cur <= k && node[cur].kth == cnt ) ans[node[cur ++].idx] = i ;
}
a[i & 63] = 0 ;
a[( i + num[i / 10000] + num[i % 10000] ) & 63] = 1 ;
}
printf ( "%d\n" , cnt ) ;
For ( i , 1 , k ) printf ( "%d%c" , ans[i] , i < k ? ' ' : '\n' ) ;
}
int main () {
while ( ~scanf ( "%d%d" , &n , &k ) ) solve () ;
return 0 ;
}