題目涉及算法:
- 標題統計:字符串入門題;
- 龍虎斗:數學題;
- 擺渡車:動態規划;
- 對稱二叉樹:搜索。
標題統計
題目鏈接:https://www.luogu.org/problem/P5015
這道題目是一道基礎題,考察你字符(串)的輸入。
實現代碼如下:
#include <cstdio>
char c;
int cnt;
int main() {
while (c = getchar()) {
if (c == EOF || c == '\n') break;
if (c != ' ') cnt ++;
}
printf("%d\n", cnt);
return 0;
}
龍虎斗
題目鏈接:https://www.luogu.org/problem/P5016
這道題目是一道簡單的數學推理題。
但是它有一些條件是可以化簡的,比如“某一刻天降神兵,共有 \(s_1\) 位工兵突然出現在了 \(p_1\) 號兵營”這個條件,你是可以直接處理成一開始這 \(s_1\) 位工兵就出現在 \(p_1\) 位置的。
取出多余條件之后,實現的時候從左到右枚舉一下勢力和之差即可。
實現代碼如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, m, p1, p2;
long long a[maxn], s1, s2, sum;
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
cin >> m >> p1 >> s1 >> s2;
a[p1] += s1;
p2 = 1;
for (int i = 1; i <= n; i ++)
sum += ( (long long) (i - m) ) * a[i];
for (int i = 1; i <= n; i ++)
if ( abs(sum + (i-m) * s2) < abs(sum + (p2-m) * s2) ) p2 = i;
cout << p2 << endl;
return 0;
}
擺渡車
題目鏈接:
本題涉及算法:動態規划,有一丟丟貪心的思想。
我們令 \(f[i]\) 表示在時刻 \(i\) 發車時所有最晚在時刻 \(i\) 到站的人的最少等待時間,則:
\(f[i]\) 只跟范圍在 \((i-2*m, i-m]\) 的 \(f[j]\) 有關,因為對於任意 \(i\) 來說:
\(f[i] \le f[i-m]\) (因為 \(i-m\) 時刻發車,我 \(i\) 又回來了)。
那么我令 \(tmp_{j,i}\) 表示時刻 \(j\) 開始到時刻 \(i\) 到站的人的總等待時長,則:
\(f[i] = \max(f[j]+tmp_{j,i})\) (其中 \(i-2 \times m \lt j \le i-m\) )。
實現代碼如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4000400;
int n, m, t, maxt;
long long f[maxn], cnt[maxn];
int main() {
cin >> n >> m;
for (int i = 0; i < n; i ++) {
cin >> t;
cnt[t] ++;
if (t > maxt) maxt = t;
}
for (int i = 0; i <= maxt + m; i ++) {
long long tmp = 0;
for (int j = 0; j < m && i-j >=0; j ++) {
tmp += cnt[i-j] * ( (long long) j );
}
f[i] = tmp;
if (i >= m) f[i] += f[i-m];
for (int j = m+1; j <= 2*m && i - j >= 0; j ++) {
tmp += cnt[i-j+1] * ( (long long) (j-1) );
if (f[i-j] + tmp <= f[i]) f[i] = f[i-j] + tmp;
}
}
long long ans = f[maxt];
for (int i = 1; i <= m; i ++) {
ans = min(ans, f[maxt+i]);
}
cout << ans << endl;
return 0;
}
對稱二叉樹
題目鏈接:https://www.luogu.org/problem/P5018
這道題目用搜索竟然過了。
表示這樣的話最壞情況下時間復雜度應該有 \(O(n^2)\) 囧、
另說標准解法應該是樹hash,有時間了解一下。
實現代碼如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 4000400;
int n, m, t, maxt;
long long f[maxn], cnt[maxn];
int main() {
cin >> n >> m;
for (int i = 0; i < n; i ++) {
cin >> t;
cnt[t] ++;
if (t > maxt) maxt = t;
}
for (int i = 0; i <= maxt + m; i ++) {
long long tmp = 0;
for (int j = 0; j < m && i-j >=0; j ++) {
tmp += cnt[i-j] * ( (long long) j );
}
f[i] = tmp;
if (i >= m) f[i] += f[i-m];
for (int j = m+1; j <= 2*m && i - j >= 0; j ++) {
tmp += cnt[i-j+1] * ( (long long) (j-1) );
if (f[i-j] + tmp <= f[i]) f[i] = f[i-j] + tmp;
}
}
long long ans = f[maxt];
for (int i = 1; i <= m; i ++) {
ans = min(ans, f[maxt+i]);
}
cout << ans << endl;
return 0;
}