A. Beru-taxi(Codeforces 706A)
思路
我们可以枚举出租车,然后用两点间距离公式计算用时的用时更新最优解。
代码
#include <bits/stdc++.h>
using namespace std;
int n;
double a, b, x, y, v, ans;
double sqr(double x) {
return x * x;
}
double dis(int x1, int y1, int x2, int y2) {
return sqrt(sqr(x1 - x2) + sqr(y1 - y2));
}
int main() {
cin >> a >> b >> n;
ans = 1e9;
for(int i = 1; i <= n; i++) {
cin >> x >> y >> v;
ans = min(ans, dis(a, b, x, y) / v);
}
printf("%.10f\n", ans);
return 0;
}
B. Interesting drink(Codeforces 706B)
思路
本题需要我们动态地在给定的序列
x
中求出比
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, q, m, idx, a[maxn];
int main() {
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
sort(a, a + n);
scanf("%d", &q);
while(q--) {
scanf("%d", &m);
idx = upper_bound(a, a + n, m) - a;
printf("%d\n", idx);
}
return 0;
}
C. Hard problem(Codeforces 706C)
思路
如果我们能知道到第 i−1 个字符串为止,在不反转和反转第 i−1 个字符串情况下的最优解 d[i−1][0] 和 d[i−1][1] ,我们就能知道 d[i][0] 和 d[i][1] 的情况。因此我们可以用个动态规划来解决这个问题。首先预处理出第i个原串 s[i][0] 和其反转后的字符串 s[i][1] ,然后进行初始化 d[1][0]=0,d[1][1]=c[1] ,接着按照方程
d[i][j]=min(d[i][j],d[i−1][k]+j×c[i]),if(s[i][j]≥s[i−1][k])
进行递推,最后 min(d[n][0],d[n][1]) 就是答案。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll INF = (1LL << 60);
int n;
ll ans, cost, c[maxn], d[maxn][2];
string s[maxn][2];
int main() {
ios::sync_with_stdio(false);
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> c[i];
}
for(int i = 1; i <= n; i++) {
cin >> s[i][0];
s[i][1] = s[i][0];
// 预处理出反转后的字符串
reverse(s[i][1].begin(), s[i][1].end());
}
d[1][1] = c[1];
for(int i = 2; i <= n; i++) {
// 初始化d[i][0]和d[i][1]
d[i][0] = d[i][1] = INF;
// 枚举第i个字符串的摆放方式(反转还是不反转)
for(int j = 0; j <= 1; j++) {
// 枚举第i-1个字符串的摆放方式
for(int k = 0; k <= 1; k++) {
if(s[i][j] < s[i-1][k]) {
continue;
}
cost = j * c[i];
d[i][j] = min(d[i][j], d[i-1][k] + cost);
}
}
}
ans = min(d[n][0], d[n][1]);
cout << (ans == INF ? -1 : ans) << endl;
return 0;
}
D. Vasiliy’s Multiset(Codeforces 706D)
思路
首先,可以用
map
来维护多重集。其次,可以用
Trie
来维护一个集合,并且能够对给定的
x
快速找出集合中的y使得
代码
#include <bits/stdc++.h>
using namespace std;
const int maxNode = 1e7;
char s[10];
int q, x, ans;
map <int, int> mp;
// Trie的模板
struct trie {
int sz, val[maxNode], ch[maxNode][2];
void init() {
memset(ch[0], 0, sizeof(ch[0]));
sz = 1;
}
void update(int num, int v) {
int u = 0;
for(int i = 30; i >= 0; i--) {
int c = (num >> i) & 1;
if(ch[u][c] == 0) {
memset(ch[sz], 0, sizeof(ch[sz]));
val[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
val[u] += v;
}
}
int match(int num) {
int u = 0, ans = 0;
for(int i = 30; i >= 0; i--) {
int c = (num >> i) & 1;
if(ch[u][c^1] && val[ch[u][c^1]]) {
ans |= (1 << i);
u = ch[u][c^1];
}
else u = ch[u][c];
}
return ans;
}
}o;
int main() {
o.init();
o.update(0, 1);
scanf("%d", &q);
while(q--) {
scanf("%s%d", s, &x);
if(s[0] == '+') {
if(mp[x]++ == 0) {
o.update(x, 1);
}
}
if(s[0] == '-') {
if(--mp[x] == 0) {
o.update(x, -1);
}
}
if(s[0] == '?') {
printf("%d\n", o.match(x));
}
}
return 0;
}