20161111测试总结

T1

此题考语文,注意题意的理解…
贪心,特判偶数串就行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <bits/stdc++.h>
using namespace std;
int sum, cnt, k;
int main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
sum = cnt = 0;
for (int i = 1; i <= n; i++)
cin >> k, sum += k / 2, cnt += k % 2;
if (cnt) cout << 1 + (sum / cnt) * 2 << "\n";
else cout << sum * 2 << "\n";
}
return 0;
}

T2

记忆化搜索,下次不作死写十重 $for$ 循环了…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50;
typedef long long ll;
int f[MAXN];
map<ll, int> dp;
inline ll hash(int t, int k, int x) {
return (ll)t * 11 * 1000000001 + (ll)k * 1000000001 + x;
}
inline int dfs(int now, int x, int k) {
if (!x) return k == 0;
if (now < 0) return 0;
if ((ll)f[now] * k < x) return 0;
ll tmp = hash(now, k, x);
if (dp.count(tmp)) return dp[tmp];
register int ret = 0;
for (register int i = 0; i <= k; i++) {
if (i * f[now] > x) break;
else ret += dfs(now - 1, x - i * f[now], k - i);
}
return dp[tmp] = ret;
}
int main() {
f[0] = 1, f[1] = 2;
register int i, r = 1e9;
for (i = 1; f[i] <= r; i++) f[i + 1] = f[i] + f[i - 1];
register int t;
cin >> t;
while (t--) {
int x, k;
cin >> x >> k;
cout << dfs(i - 1, x, k) << "\n";
}
return 0;
}

T3

倍增或神奇的”快速幂”就能实现,复杂度为$O(n \log n)$。
但此题我们可以把一个石头向它第 $k$ 近的石头连边,那么这就形成了一张有向图,每个点只有一个出度,所以这张图必然是一些基环套内向树的形式,那么就可以 $BFS$ 搜出每个点能否进入基环,以及进入基环的位置和步数,就可以求出答案,这样的时间复杂度位$O(n)$。

$O(n \log n)$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <bits/stdc++.h>
using namespace std;
const int iol = 1024 * 1024;
bool iosig;
char ch, buf[iol], *s, *t;
inline char read() {
if (s == t) {
t = (s = buf) + fread(buf, 1, iol, stdin);
if (s == t) return -1;
}
return *s++;
}
template<class T>
inline bool read(T &x) {
iosig = 0;
for (ch = read(); !isdigit(ch); ch = read()) {
if (ch == -1) return false;
if (ch == '-') iosig = true;
}
x = 0;
while (ch == '0') ch = read();
for (; isdigit(ch); ch = read())
x = (x << 1) + (x << 3) + (ch ^ '0');
if (iosig) x = -x;
return true;
}
const int MAXN = 1000010;
int n, k, ans[MAXN];
long long a[MAXN], m;
int f[MAXN], g[MAXN];
int main() {
read(n), read(k), read(m);
k++;
for (register int i = 1; i <= n; i++)
read(a[i]);
register int l = 1, r = k;
for (register int i = 1; i <= n; i++) {
while ((r < n) && (a[r + 1] - a[i] < a[i] - a[l]))
l++, r++;
if (a[i] - a[l] >= a[r] - a[i]) f[i] = l;
else f[i] = r;
}
for (register int i = 1; i <= n; i++)
ans[i] = i;
while (m) {
if (m & 1)
for (register int i = 1; i <= n; i++)
ans[i] = f[ans[i]];
m >>= 1;
for (register int i = 1; i <= n; i++)
g[i] = f[f[i]];
memcpy(f, g, sizeof(int) * (n + 1));
}
for (register int i = 1; i <= n; i++)
cout << ans[i] << " ";
cout << "\n";
return 0;
}

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×