题目大意
某个监狱包含n个牢房的长廊,每个牢房彼此相邻。 每个牢房中都有一个囚犯,每个牢房都被锁定。
一天晚上,狱卒感到无聊,决定玩游戏。 在比赛的第一轮中,他喝了一杯威士忌,然后跑到大厅解锁每个牢房。 在第二轮中,他喝了一杯威士忌,然后沿着
霍尔锁定其他所有单元(单元2、4、6 、?)。 在第三回合中,他喝了一杯威士忌,然后奔向大厅。 他每隔三个单元(单元3、6、9 、?)访问一次。 如果单元被锁定,他将其解锁; 如果已解锁,他将其锁定。 他
重复此操作n轮,喝最后一杯,然后昏倒。
一定数量的囚犯(可能为零)意识到他们的牢房已解锁并且囚犯无能为力。 他们立即逃脱。
根据牢房的数量,确定有多少囚犯逃离监狱。
思路分析
显然模拟是可以做出来的,但是并不是最优的,
#include<iostream>
#include<iomanip>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 101
#define ll long long
ll vis[MAX];
int main() {
ll n; cin >> n;
while (n--) {
ll a, cnt = 2, res = 0; cin >> a;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < a; i++) {
for (ll j = cnt; j <= a; j += cnt) vis[j] += 1;
cnt++;
}
for (ll i = 1; i <= a; i++) {
if (vis[i] % 2 == 0) res++;
}
cout << res << endl;
}
}
模拟也不会很慢
我们不妨推倒一下这些数字背后的秘密
n 逃跑数 逃跑序号
1 1 1
2 1 1
3 1 1
4 2 1,4
5 2 1,4
6 2 1,4
7 2 1,4
8 2 1,4
9 3 1,4,9
欸,到9的时候好像就出现规律了,我们发现只要不是一个完全平方数,他总不能跑,为什么呢?观察一下这些完全平方数,他们都能拆成 n ∗ n n*n n∗n的形式,那么就保证第 n n n轮,第 n ∗ n n*n n∗n轮都会关一次门,这两个加起来是偶数。然后如果 n ∗ n n*n n∗n不能再拆分成其他因子的积 9 9 9,那就结束了,只操作了两次,最终是开的。如果可以拆成 a ∗ b a*b a∗b的形式,那第 a , b a,b a,b轮会分别操作他一次,结果依然是开的。成功优化
#include<iostream>
#include<iomanip>
#include<string.h>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll int
int main() {
ll n; cin >> n;
while (n--) {
ll a, cnt = 2, res = 0; cin >> a;
ll b = sqrt(double(a));
cout << b << endl;
}
}