A. The New Year: Meeting Friends(Codeforces 723A)
思路
因爲所求的座標的範圍比較小,因此直接枚舉這個座標,同時更新答案即可。
代碼
#include <bits/stdc++.h>
using namespace std;
int a, b, c, res, ans;
int main() {
scanf("%d%d%d", &a, &b, &c);
ans = 400;
for(int i = 1; i <= 100; i++) {
res = abs(a - i) + abs(b - i) + abs(c - i);
ans = min(res, ans);
}
printf("%d\n", ans);
return 0;
}
B. Text Document Analysis(Codeforces 723B)
思路
首先將括號外的字符串和括號內的字符串分離開。方法是先定位所有括號,然後將所有括號中的字符串用 _ 字符連接起來放在一個新的字符串中,再用 _ 字符將原字符串中括號中的字符串(包括括號)屏蔽掉。
接着將兩個字符串中非字母的字符改成空格,並將他們分別製作成字符串流,最後從字符串流中邊輸入邊統計即可得到答案。
代碼
#include <bits/stdc++.h>
using namespace std;
int n, idx, x, y;
string s, t;
int main() {
ios_base::sync_with_stdio(false);
cin >> n >> s;
for(int i = 0; i < n; i++) {
if(s[i] == '(') {
idx = i;
}
if(s[i] == ')') {
t = t + "_" + s.substr(idx + 1, i - idx - 1);
for(int j = idx; j <= i; j++) {
s[j] = '_';
}
}
}
for(int i = 0; i < s.size(); i++) {
if(s[i] == '_' || s[i] == '(' || s[i] == ')') {
s[i] = ' ';
}
}
for(int i = 0; i < t.size(); i++) {
if(t[i] == '_' || t[i] == '(' || t[i] == ')') {
t[i] = ' ';
}
}
stringstream in(t);
stringstream out(s);
while(out >> s) {
x = max(x, (int)s.size());
}
while(in >> s) {
y++;
}
cout << x << ' ' << y << endl;
return 0;
}
C. Polycarp at the Radio(Codeforces 723C)
思路
首先肯定可以將所有不是編號
接下來的事情就簡單了,我們先枚舉不是
實現上,爲了動態瞭解那個樂隊的演奏曲目最少,可以用堆將每個樂隊對曲目的“需求”維護起來(但是這題的數據量比較小,貌似暴力也行)。
代碼
#include <bits/stdc++.h>
using namespace std;
typedef pair <int, int> p;
const int maxn = 2010;
int n, m, need, cnt, idx, dif, a[maxn], b[maxn];
priority_queue <p> pq;
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if(a[i] <= m) {
b[a[i]]++;
}
}
need = n / m;
for(int i = 1; i <= m; i++) {
if(b[i] < need) {
pq.push(p(need - b[i], i));
}
}
for(int i = 1; i <= n; i++) {
if(pq.empty()) {
break;
}
if(a[i] > m) {
p tmp = pq.top();
pq.pop();
idx = tmp.second;
dif = tmp.first;
a[i] = idx;
b[idx]++;
cnt++;
if(dif > 1) {
pq.push(p(dif - 1, idx));
}
}
}
for(int i = 1; i <= n; i++) {
if(pq.empty()) {
break;
}
if(b[a[i]] > need) {
p tmp = pq.top();
pq.pop();
idx = tmp.second;
dif = tmp.first;
b[a[i]]--;
b[idx]++;
a[i] = idx;
cnt++;
if(dif > 1) {
pq.push(p(dif - 1, idx));
}
}
}
printf("%d %d\n", need, cnt);
for(int i = 1; i <= n; i++) {
printf("%d ", a[i]);
}
puts("");
return 0;
}
D. Lakes in Berland(Codeforces 723D)
思路
先用
代碼
#include <bits/stdc++.h>
using namespace std;
// 將與湖有關的信息封裝起來以便排序
struct lake {
int x, y, area;
lake() {}
lake(int x, int y, int area): x(x), y(y), area(area) {}
bool operator < (const lake& o) const {
return area < o.area;
}
};
const int maxn = 60;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
bool vis[maxn][maxn];
char G[maxn][maxn];
int n, m, k, res, ans, del;
vector <lake> v;
// 在圖中找連通分量(湖)
int dfs(int x, int y) {
vis[x][y] = true;
// 如果臨海的話就返回-1
if(G[x][y] == 0) {
return -1;
}
int res = 0;
bool ok = true;
// 向四個相鄰的方向走
for(int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if(G[nx][ny] == '*' || vis[nx][ny]) {
continue;
}
int t = dfs(nx, ny);
// 如果發現臨海就標記一下
if(t == -1) {
ok = false;
}
res += t;
}
return ok ? res + 1 : -1;
}
// 在圖中填湖
void land(int x, int y) {
G[x][y] = '*';
for(int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if(G[nx][ny] != '*') {
land(nx, ny);
}
}
}
int main() {
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++) {
scanf("%s", G[i] + 1);
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(G[i][j] == '*' || vis[i][j]) {
continue;
}
res = dfs(i, j);
if(res == -1) {
continue;
}
v.push_back(lake(i, j, res));
}
}
del = v.size() - k;
// 按照面積對湖排序
sort(v.begin(), v.end());
for(int i = 0; i < del; i++) {
ans += v[i].area;
land(v[i].x, v[i].y);
}
printf("%d\n", ans);
for(int i = 1; i <= n; i++) {
printf("%s\n", G[i] + 1);
}
puts("");
return 0;
}
E. One-Way Reform(Codeforces 723E)
思路
首先顯然每個偶度數的點都能夠達到入度等於出度的狀態。奇度數的點則必然不行。但是奇度數的點可以配合偶度數的點使其達到入度等於出度的狀態。
這樣的狀態讓我們想起歐拉回路。
正好對於每個連通分量奇度數的點的數量都是偶數。那麼我們對奇度數的點之間建立無向邊。這樣原圖就變成能夠構成歐拉回路的圖(正好各個連通分量之間也連通了)。實現起來是設置一個虛擬節點
最後在用
代碼
#include <bits/stdc++.h>
using namespace std;
const int maxn = 205;
bool vis[maxn][maxn];
int t, n, m, u, v, ans;
vector <int> G[maxn];
void dfs(int u) {
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if(vis[u][v]) {
continue;
}
vis[u][v] = vis[v][u] = true;
if(u > 0 && v > 0) {
printf("%d %d\n", u, v);
}
dfs(v);
}
}
int main() {
scanf("%d", &t);
while(t--) {
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; i++) {
G[i].clear();
}
for(int i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
ans = 0;
for(int i = 1; i <= n; i++) {
if(G[i].size() & 1) {
G[0].push_back(i);
G[i].push_back(0);
}
else {
ans++;
}
}
printf("%d\n", ans);
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++) {
dfs(i);
}
}
return 0;
}