Loading

【题解】[CCO2021] Weird Numeral System

敢想敢写。。。

我们直接定义状态 \(f_{i}\) 表示数 \(i\) 能否被表示出来。

然后我们枚举最低位 \(a_x\),如果 \(k | (i - a_{x})\) 就可以从 \(f_{(i - a_{x}) / k}\) 转移到 \(f_{i}\)。因为次低位一定是 \(k\) 的倍数,所以当前 \(i\) 减去 \(a_x\) 一定是 \(k\) 的倍数。

由于 \(a_{x}\) 可以是负数,所以 \((i -a_{x})/k\) 可以等于 \(i\),相当于自己转移自己,会无线递归下去,这种情况特判掉。

貌似状态数是 \(10^{18}\) ,转移也有 \(800\),但无用状态非常多,并且如果 \(D\) 比较大,那么大概率可以表示任意一个数,而我们搜到一个方案就结束了。

#define N 1005
int k, n, m, q, a[N];
unordered_map<LL, bool> f;
vector<int>ans;
bool calc(LL x){
	if(f.count(x))return false;
	f[x];
	rp(i, n)if(a[i] == x){
		ans.pb(a[i]);
		return true;
	}
	rp(i, n){
		if((x - a[i]) % k == 0 && (x - a[i]) / k != x && calc((x - a[i]) / k)){
			ans.pb(a[i]); return true;
		}
	}
	return false;
}
int main() {
	read(k, q, n, m);
	rp(i, n)read(a[i]);
	while(q--){
		LL x; read(x);
		f.clear(), ans.clear();
		if(calc(x)){
			go(y, ans)printf("%d ", y); el;
		}
		else puts("IMPOSSIBLE");
	}
	return 0;
}
posted @ 2022-02-08 10:52  7KByte  阅读(190)  评论(0编辑  收藏  举报