180429华中科技大学程序设计竞赛题解 K题:Walking in the Forest B题:Beautiful Trees Cutting F题:Sorting Trees C题:Professional Manager

题解按AC数降序排列。

简单bfs。

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


#define x first
#define y second
#define ok cout << "ok" << endl;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const double PI = acos(-1.0);
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const int N=1e6+39;
const int shift=1e3+9;
const double Eps=1e-7;

int cnt[N];

void (int u, int v) {
bool vis[N];
int dis[N];
queue<int> que;
memset(vis, 0, sizeof vis);
memset(dis, INF, sizeof dis);
dis[u] = 0;
vis[u] = 1;
que.push(u);
while(que.size()) {
int uu = que.front();
que.pop();
if(uu == v) {
printf("%dn", dis[v]);
break;
}
if(uu + 1 < N && !vis[uu + 1]) {
dis[uu + 1] = dis[uu] + 1;
vis[uu + 1] = 1;
que.push(uu + 1);
}
if(uu - 1 >= 0 && !vis[uu - 1]) {
dis[uu - 1] = dis[uu] + 1;
vis[uu - 1] = 1;
que.push(uu - 1);
}
if(uu + cnt[uu] < N && !vis[uu + cnt[uu]]) {
dis[uu + cnt[uu]] = dis[uu] + 1;
vis[uu + cnt[uu]] = 1;
que.push(uu + cnt[uu]);
}
if(uu - cnt[uu] >= 0 && !vis[uu - cnt[uu]]) {
dis[uu - cnt[uu]] = dis[uu] + 1;
vis[uu - cnt[uu]] = 1;
que.push(uu - cnt[uu]);
}
}
}

void pre() {
memset(cnt, 0, sizeof cnt);
for(int i = 1; i < N; i++) {
int t = i;
while(t) {
if(t & 1)
cnt[i]++;
t >>= 1;
}
}
}

int main(void) {
if(fopen("in", "r")!=NULL) {freopen("in", "r", stdin); freopen("out", "w", stdout);}
pre();
int a, b;
while(cin >> a >> b)
bfs(a, b);

return 0;
}

K题:Walking in the Forest

简单二分。

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


#define x first
#define y second
#define ok cout << "ok" << endl;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const double PI = acos(-1.0);
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const int N=1e5+9;
const int shift=1e3+9;
const double Eps=1e-7;

int k, n, a[N];

bool check(ll mid) {
ll sum = LINF, cnt = 0;
for(int i = 0; i < k; i++) {
if(a[i] > mid)
return false;
if(sum + a[i] > mid)
sum = a[i], cnt++;
else
sum += a[i];
}
return cnt <= n;
}

int main(void) {
if(fopen("in", "r")!=NULL) {freopen("in", "r", stdin); freopen("out", "w", stdout);}
while(~scanf("%d%d", &k, &n)) {
k--;
for(int i = 0; i < k; i++)
scanf("%d", a + i);
ll l = 0, r = 10000000000;
while(l < r) {
ll mid = (l + r) >> 1;
if(check(mid))
r = mid;
else
l = mid + 1;
}
printf("%lldn", r);
}

return 0;
}

B题:Beautiful Trees Cutting

简单数学题。

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


#define x first
#define y second
#define ok cout << "ok" << endl;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const double PI = acos(-1.0);
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const int N=1e5+9;
const int shift=1e3+9;
const double Eps=1e-7;

const int mod = 1e9 + 7;

char s[N];
ll ans, m, n;
vi v;

ll ksm(ll a, ll b) {
ll ans = 1;
while(b) {
if(b & 1)
(ans *= a) %= mod;
(a *= a) %= mod;
b >>= 1;
}
return ans;
}

int main(void) {
if(fopen("in", "r")!=NULL) {freopen("in", "r", stdin); freopen("out", "w", stdout);}
while(cin >> m >> s) {
v.clear();
n = strlen(s);
for(int i = 0; i < n; i++)
if((s[i] - '0') % 5 == 0)
v.push_back(i);
ans = 0;
for(int i = 0; i < v.size(); i++)
(ans += ksm(2, v[i])) %= mod;
(ans *= ksm(2, n * m) - 1) %= mod;
(ans *= ksm(ksm(2, n) - 1, mod - 2)) %= mod;
printf("%lldn", ans % mod);
}

return 0;
}

F题:Sorting Trees

简单思维题。之前在Codejam上做过在k = 2情况下的一道题,这道题算是对那道题的推广。

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
59
60


#define x first
#define y second
#define ok cout << "ok" << endl;
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const double PI = acos(-1.0);
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const int N=1e5+9;
const int shift=1e3+9;
const double Eps=1e-7;

vi v[N];
int n, k, a[N], b[N];

int main(void) {
if(fopen("in", "r")!=NULL) {freopen("in", "r", stdin); freopen("out", "w", stdout);}
while(cin >> n >> k) {
for(int i = 0; i < n; i++)
scanf("%d", a + i);
if(k == 0) {
memcpy(b, a, sizeof a);
sort(b, b + n);
int i;
for(i = 0; i < n; i++)
if(a[i] != b[i]) {
printf("%dn", i + 1);
break;
}
if(i == n)
printf("-1n");
continue;
}
for(int i = 0; i < n; i++)
v[i % k].push_back(a[i]);
for(int i = 0; i < k; i++) {
if(v[i].empty()) continue;
sort(v[i].begin(), v[i].end());
}
for(int i = 0; i < k; i++)
for(int j = 0; j < v[i].size(); j++)
b[i + j * k] = v[i][j];
sort(a, a + n);
int i;
for(i = 0; i < n; i++)
if(a[i] != b[i]) {
printf("%dn", i + 1);
break;
}
if(i == n)
printf("-1n");
}

return 0;
}

C题:Professional Manager

留坑待补。