SP1798 ASSIST - Assistance Required 题解

Content

有一个足够长的数列 \(a\),是一个首项为 \(2\),公差为 \(1\) 的等差递增数列。另有一个初始为空的数列 \(b\)。

重复进行如下操作:

  • 假设当前数列 \(a\) 第一项为 \(x\)。将 \(x\) 放在数列 \(b\) 的最后。
  • 不断将第 \(kx+1(k\in\mathbb N^*)\) 项丢出数列 \(a\) 且不放入数列 \(b\)

求出最后得到的序列 \(b\) 的第 \(n\) 项。

数据范围:\(1\leqslant n\leqslant 3000\)。

Solution

这题看上去很难,但事实上呢?是一道暴力题。

由于枚举到 \(35000\) 的时候数列 \(b\) 就已经超过了 \(3000\) 项,所以我们考虑从 \(2\) 到 \(35000\) 枚举,一个一个去标记,得到数列 \(b\),然后就可以直接 \(\mathcal O(1)\) 查询了。

由于能够加入数列 \(b\) 的数有限,因此可以保证这样枚举不会超过时限。

Code

namespace Solution {
	int cnt, vis[40007], ans[4007];
	
	iv getans() {
		F(int, i, 2, 35007) if(!vis[i]) {
			vis[i] = 1;
			int cnt2 = 0;
			F(int, j, i + 1, 35007) if(!vis[j]) {
				cnt2++;
				if(cnt2 == i) vis[j] = 2, cnt2 = 0;
			}
		}
		F(int, i, 2, 35007) if(vis[i] == 1) ans[++cnt] = i;
	}
	
	iv Main() {
		getans();
		while(1) {
			int n; read(n); 
			if(!n) break;
			println(ans[n]);
		}
		return;
	}
}
上一篇:CF615A Bulbs 题解


下一篇:linux5--- liunx5基础操作(6)