A
直接最长边
相当于等腰梯形
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 1e5 + 5;
int n, m, _, k;
int a[4];
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> a[1] >> a[2] >> a[3];
sort(a + 1, a + 1 + 3);
cout << a[3] << '
';
}
return 0;
}
B
找就行了
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 1e5 + 5;
int n, m, _, k;
ll a[105][105], b[5];
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n >> m; ll ans = 0;
rep (i, 1, n) rep (j, 1, m) cin >> a[i][j];
rep (i, 1, n + 1 >> 1)
rep (j, 1, m + 1 >> 1) {
if (i == n - i + 1 && j == m - j + 1) continue;
if (i == n - i + 1) { ans += abs(a[i][j] - a[i][m - j + 1]); continue; }
if (j == m - j + 1) { ans += abs(a[i][j] - a[n - i + 1][j]); continue; }
b[1] = a[i][j]; b[2] = a[i][m - j + 1];
b[3] = a[n - i + 1][j]; b[4] = a[n - i + 1][m - j + 1];
ll mi = 2e18;
rep (p, 1, 4) {
ll res = 0;
rep (q, 1, 4) res += abs(b[p] - b[q]);
umin(mi, res);
}
ans += mi;
}
cout << ans << '
';
}
return 0;
}
C
自闭了, 挂机了1h+, 掉分了≡(▔﹏▔)≡
对于每一位, 分别计算就行了, 看看代码就明白了
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 1e5 + 5, mod = 1e9 + 7;
int n, m, _, k;
ll sum[N], a[N], t[N] = {1};
char s[N];
int main() {
IOS; cin >> s + 1; n = strlen(s + 1);
rep(i, 1, 1e5) {
t[i] = t[i - 1] * 10 % mod;
a[i] = (a[i - 1] + i) % mod;
sum[i] = i * t[i - 1] % mod;
sum[i] = (sum[i - 1] + sum[i]) % mod;
}
ll ans = 0;
per(i, n, 1) {
ans = (ans + (s[i] ^ 48) * sum[n - i] % mod) % mod;
ans = (ans + (s[i] ^ 48) * a[i - 1] % mod * t[n - i]) % mod;
}
cout << ans;
return 0;
}
D
最短路, 当然你 m * m建边必t
要贪心的去建边
对于 传送站 i((x_i), y_i), j((x_j, y _j)) ((x_i <= x_j))
距离则为min(abs((x_i - x_j)), ((y_i, y_j)))
假设 abs((x_i - x_j)) <= ((y_i, y_j)), 存在传送站 k((x_k, y_k)) 且((y_k == y_i) && ((x_i <= x_k <= x_j))), 那么i和j的距离可能会更新(最少不会增加)
所以我们应该直接先去找这样的 k, 就有了 (i,k) (k, j) 建边而不是 三个传送站两两建边, 建边就被优化了
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
template<class T1, class T2> bool umin(T1& a, T2 b) { return a > b ? (a = b, true) : false; }
template<class T1, class T2> bool umax(T1& a, T2 b) { return a < b ? (a = b, true) : false; }
template<class T> void clear(T& a) { T().swap(a); }
const int N = 1e5 + 5, mod = 1e9 + 7;
const ll inf64 = 1e18;
int n, m, _, k;
int main() {
IOS; cin >> n >> m;
vector<ll[2]> pos(m + 2);
cin >> pos[m][0] >> pos[m][1] >> pos[m + 1][0] >> pos[m + 1][1];
rep(i, 0, m - 1) cin >> pos[i][0] >> pos[i][1];
vector<vector<pair<ll, int>>> e(m + 2);
rep(i, 0, m) e[i].pb({ abs(pos[i][0] - pos[m + 1][0]) + abs(pos[i][1] - pos[m + 1][1]), m + 1 });
rep(k, 0, 1) {
vector<pair<ll, int>> a(m + 1);
rep(i, 0, m) a[i] = { pos[i][k], i };
sort(all(a));
rep(i, 1, m) {
ll d = a[i].fi - a[i - 1].fi;
int x = a[i].se, y = a[i - 1].se;
e[x].pb({ d, y }); e[y].pb({ d, x });
}
}
vector<bool> v(m + 2); vector<ll> d(m + 2, inf64); d[m] = 0;
priority_queue<pair<ll, int>> q; q.push({ -0, m });
while (!q.empty()) {
int x = q.top().se; q.pop();
if (v[x]) continue; v[x] = 1;
for (auto& i : e[x]) {
int y = i.se; ll w = i.fi;
if (d[y] <= d[x] + w) continue;
d[y] = d[x] + w;
q.push({ -d[y], y });
}
}
cout << d[m + 1] << '
';
return 0;
}
E
先看清题是最重要的, 是选择 s[i] == s[i + 1] 的删掉, 一次性, 不会因为删除 i, i + 1之后 i + 2 就会变成 i, (wa46)
因为要求最小字典序, 所以倒着求(只有这样, 在 i 处, i + 1~n 的序列是确定的, 才能和 i + 2~n 的后缀比大小)
维护一下 ne[i], 大于节点i 且 s[ne[i]] != s[i] 的最小值 (用来比大小)
同时我们还要维护一个 当前最近, 次近(用来在 最近被删除时 得到新的最近未被删除)未被删除的节点下标
为什么不能用 ne[i] 存呢?
cxxxzzxca
对于 (从0开始) ne[1] = 7(最近未被删除是 s[6] == 'x')
到了 i == 0, s[ne[i + 1] = 7] == s[i], ne[i] = ne[ne[i + 1]] = 8
然而真正的 ne[i = 0] = 6 (s[6] == 'x'), 这就是我wa了半天 47 的地方
int a, b, len[N], lens, ne[N];
string s, ans[N], cur;
void solve(int x) {
cur += s[x];
if (s[x] != s[a]) ne[x] = a;
else ne[x] = ne[a];
b = a; a = x;
len[x] = cur.size();
if (cur.size() <= 10) ans[x] = cur, reverse(all(ans[x]));
else {
string t = cur.substr(cur.size() - 5, 5); reverse(all(t));
ans[x] = t + "..." + cur[1] + cur[0];
}
}
int main() {
IOS; cin >> s; a = lens = s.size();
s += char(0); ne[lens] = lens;
per(i, lens - 1, 0) {
if (s[i] != s[i + 1]) solve(i);
else if (i + 1 == a && s[ne[i + 1]] < s[i]) {
a = b; cur.pop_back();
len[i] = len[i + 2]; ans[i] = ans[i + 2];
}
else solve(i);
}
rep(i, 0, lens - 1) cout << len[i] << ' ' << ans[i] << '
';
return 0;
}