A 369
问题:
思路:暴力枚举
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
int cnt = 0;
for(int i = -1000; i <= 1000; i ++ ) {
vector<int> aa;
aa.push_back(a);
aa.push_back(b);
aa.push_back(i);
sort(aa.begin(), aa.end());
if(aa[1] - aa[0] == aa[2] - aa[1]) cnt ++;
}
cout << cnt << endl;
return 0;
}
B Piano 3
问题:
思路:贪心的将手的初始位置设为第一个键位所在的位置
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n + 1);
vector<char> s(n + 1);
for(int i = 1; i <= n; i ++ ) cin >> a[i] >> s[i];
int cl = -1, cr = -1;
int lastl = 0, lastr = 0;
for(int i = 1; i <= n; i ++ ) {
if(s[i] == 'L') {
if(cl == -1) {
cl = 0;
lastl = a[i];
} else {
cl += abs(a[i] - lastl);
lastl = a[i];
}
} else {
if(cr == -1) {
cr = 0;
lastr = a[i];
} else {
cr += abs(a[i] - lastr);
lastr = a[i];
}
}
}
cout << max(0, cl) + max(0, cr);
return 0;
}
C Count Arithmetic Subarrays
问题:
思路:
开一个interval数组储存所有满足题意的子段
代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<long long> a(n + 2);
a[n + 1] = 1e18;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
long long ans = 0;
int last = a[2] - a[1];
int pos = 1;
vector<pair<int, int>> interval;
for(int i = 2; i <= n + 1; i ++ ) {
if(a[i] - a[i - 1] != last) {
last = a[i] - a[i - 1];
interval.push_back({pos, i - 1});
pos = i - 1;
}
}
for(auto t: interval) {
//cout << t.first << " " << t.second <<endl;
int num = t.second - t.first + 1;
ans += (long long)num * (num + 1) / 2;
}
cout << ans - interval.size() + 1;
return 0;
}
D Bonus EXP
问题:
思路:动态规划dp[i][j][k]表示第i个位置的怪物我是选择击杀还是不击杀以及这是我击杀的第几个(奇数个,偶数个)怪物
问题:在状态定义时一定要清楚定义,例如本题调试中由于 击杀第几个怪物的定义不明确,导致代码出错
以及在最开始dp[i][1][0]可能不会出现,因此要判断dp[i][1][0]之前的状态是否出现过
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
long long dp[N][3][3];//表示第i个我是选择击杀还是不击杀,以及这是我击杀的第几个怪物
int main() {
int n;
cin >> n;
vector<long long> a(n + 1);
bool flag = false;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
for(int i = 1; i <= n; i ++ ) {
dp[i][0][1] = max(dp[i - 1][1][1], dp[i - 1][0][1]);
dp[i][0][0] = max(dp[i - 1][1][0], dp[i - 1][0][0]);
dp[i][1][1] = max(dp[i - 1][1][0] + a[i], dp[i - 1][0][0] + a[i]);
//dp[i][1][0] = max(dp[i - 1][1][1] + a[i] * 2, dp[i - 1][0][0] + a[i] * 2)
if(dp[i - 1][1][1] != 0) dp[i][1][0] = max(dp[i][1][0], dp[i - 1][1][1] + a[i] * 2);
if(dp[i - 1][0][1] != 0) dp[i][1][0] = max(dp[i][1][0], dp[i - 1][0][1] + a[i] * 2);
}
long long ans = 0;
//n = 1;
ans = max(dp[n][0][1], dp[n][0][0]);
ans = max(ans, dp[n][1][0]);
ans = max(ans, dp[n][1][1]);
cout << ans << endl;
//cout << dp[1][1][1] << endl;
//cout << dp[2][1][0];
//cout << dp[n][1][0];
return 0;
}
E Sightseeing Tour
问题:
思路:floyd + 排列组合
黑色为必须经过的桥,不难想到,求最短路就是让红色的线最短,因此我们要准确的知道各个点之间的最短路。同时观察到n的范围很小,在o(n ^ 3)内,考虑floyd解决这个问题。并且不同的连点方式也会对答案造成影响,又注意到k,也就是固定的桥范围不超过5,并且q询问也很小,因此直接枚举所有的连点情况,先枚举桥的顺序,可以用next_permutation枚举,再用dfs枚举桥与桥之间的连接方式
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 410;
const int M = 2e5 + 10;
int g[N][N];
pair<int, int> b[M];
int len[M];
int main() {
memset(g, 0x3f, sizeof g);
int n, m;
cin >> n >> m;
for(int i = 1; i <= m; i ++ ) {
int u, v, t;
cin >> u >> v >> t;
g[u][v] = min(g[u][v], t);
g[v][u] = min(g[v][u], t);
b[i] = {u, v};
len[i] = t;
}
for(int i = 1; i <= n; i ++ ) g[i][i] = 0;
for(int k = 1; k <= n; k ++ ) {
for(int i = 1; i <= n; i ++ ) {
for(int j = 1; j <= n; j ++ ) {
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
}
}//floyd 400^3
int q;
cin >> q;
while(q -- ) {
int k;
cin >> k;
vector<int> a(k + 1);
long long ans = 1e18;
long long tmp = 0;
for(int i = 1; i <= k; i ++ ) {
cin >> a[i];
tmp += len[a[i]];
}
vector<int> alls(2 * (k + 1) + 5);
alls[1] = 1;
alls[2 * (k + 1)] = n;
function<void(int)> dfs = [&](int u) {
if(u == k + 1) {
long long res = tmp;
for(int i = 2; i <= 2 * (k + 1); i ++ ) {
res += g[alls[i]][alls[i - 1]];
}
ans = min(ans, res);
return;
}
for(int j = 1; j <= 2; j ++ ) {
if(j == 1) {
alls[2 * u] = b[u].first;
alls[2 * u + 1] = b[u].second;
} else {
alls[2 * u] = b[u].second;
alls[2 * u + 1] = b[u].first;
}
dfs(u + 1);
}
};
do {
dfs(1);
} while(next_permutation(a.begin() + 1, a.end()));
cout << ans << endl;
}
return 0;
}