A. King Moves
思路
根據棋盤的特點可以分類討論:
- 當王在棋盤的角落上時,王有
3 種走法。 - 當王在棋盤的邊緣上時,王有
5 種走法。 - 其它情況,王有
8 種走法
代碼
#include <bits/stdc++.h>
using namespace std;
string s;
int main() {
cin >> s;
if(s == "a1" || s == "h1" || s == "a8" || s == "h8") {
cout << 3;
}
else if(s[0] == 'a' || s[0] == 'h' || s[1] == '1' || s[1] == '8') {
cout << 5;
}
else {
cout << 8;
}
cout << endl;
return 0;
}
B. Optimal Point on a Line
思路
樸素的思想中,枚舉最優點,然後計算所有點到這個點的距離之和就能解決問題。但是
接下來考慮讓點有序是否對解題會有幫助,假設現在的點是按照座標的大小從小到大排列的。考慮當我們知道了第
於是在算出了
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 5;
int n, x;
ll sum, ans, a[maxn];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%I64d", &a[i]);
}
sort(a + 1, a + n + 1);
for(int i = 2; i <= n; i++) {
sum += a[i] - a[1];
}
ans = sum;
x = a[1];
for(int i = 2; i <= n; i++) {
sum += (i + i - n - 2) * (a[i] - a[i-1]);
if(sum < ans) {
ans = sum;
x = a[i];
}
}
printf("%d\n", x);
return 0;
}
C. Magic Odd Square
思路
奇數階幻方的幻和恰好也是奇數,於是問題就轉化成了如何構造奇數階幻方。(關於幻方,幻和和奇數階幻方的構造,進入這個鏈接瞭解更多)
代碼
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50;
int n, x, y, tx, ty, G[maxn][maxn];
int main() {
scanf("%d", &n);
x = 0;
y = n / 2;
for(int i = 1; i <= n * n; i++) {
G[x][y] = i;
tx = (x - 1 + n) % n;
ty = (y + 1) % n;
if(G[tx][ty] > 0) {
x++;
continue;
}
x = tx;
y = ty;
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
printf("%d ", G[i][j]);
}
puts("");
}
return 0;
}
E. Generate a String
思路
原本的思路是,因爲狀態
下面說明正確的解法:
- 當
i 爲奇數時,狀態i 從狀態i−1 或i+12 轉移過來是最優的。爲什麼是i+12 而不是i+32 或者數值更大的狀態呢?因爲從i+32 轉移過來不如先從i+32 轉移到i+32−1 再轉移到2×(i+32−1) ,即i+1 ,這樣轉移到i 的花費會更少。最後狀態轉移方程就是d[i]=min(d[i−1]+x,d[(i+1)/2]+x+y) 。 - 當
i 爲偶數時,狀態i 從狀態i−1 或i2 轉移過來是最優的。爲什麼是i2 而不是i+22 或數值更大的狀態呢?答案跟奇數的情形是類似的,這裏就不贅述了。最後狀態轉移方程就是d[i]=min(d[i−1]+x,d[i/2]+y) 。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 5;
int n, x, y;
ll d[maxn];
int main() {
cin >> n >> x >> y;
for(int i = 1; i <= n; i++) {
if(i % 2) {
d[i] = min(d[i-1] + x, d[(i+1)/2] + x + y);
}
else {
d[i] = min(d[i-1] + x, d[i/2] + y);
}
}
cout << d[n] << endl;
return 0;
}
(其它題目略)