https://codeforces.com/gym/103687
题解在cf旁边的Tutorial那里
A - JB Loves Math
本来是按照数的奇偶分类讨论,一直wa2,跑了个对拍
如果错了,可以考虑这几个样例。
由于x、y固定,所以只能考虑相差的奇偶性,而不是a、b本身的奇偶性 可以证明大转小一定能通过2步完成(+1凑奇偶 - 偶)
而小转大在相差为偶数时最少通过两步转化,关键在于凑偶数
例: 1851 6963
-> 5112 x 所以考虑拆分
-> 2556 + 2556 x
-> 2555 + 2555 + 2 x
-> 2557 + 2557 - 4 √
只能凑为 奇数 + 奇数 - 偶数(因为两个奇数必须相同)
int main() {
IOS;
int t;
cin >> t;
while(t--){
int a, b;
cin >> a >> b;
int res = 0;
if(a == b)
res = 0;
else if(a > b){
if((a - b) % 2 == 0)
res = 1;
else
res = 2;
}
else {
if((b - a) % 2)
res = 1;
else if((b - a) / 2 % 2)
res = 2;
else
res = 3;
}
cout << res << endl;
}
return 0;
}
B - JB Loves Comma
还特地判了结尾不加’,'结果wa掉,根本不用判
int main() {
IOS;
string s;
cin >> s;
if(s.find("cjb") == string::npos){
cout << s;
}
else {
while(1){
int id = s.find("cjb");
if(id == -1 || s.size() == 0)
break;
string temp = s.substr(0, id + 3);
cout << temp;
s = s.substr(id + 3, s.size());
cout << ',';
}
cout << s;
}
return 0;
}
C - JB Wants to Earn Big Money
水题
int main() {
IOS;
int n, m, k;
cin >> n >> m >> k;
int ans = 0;
for (int i = 0; i < n; ++i){
int t;
cin >> t;
if(t >= k)
++ans;
}
for (int i = 0; i < m; ++i){
int t;
cin >> t;
if(t <= k)
++ans;
}
cout << ans;
return 0;
}
G - Easy Glide
G比L好想,还是没想出来哈。想到贪心,求所有点到起点和终点的距离,然后选代价最小的,卡在了如何选择两两之间代价最小的情况,因为中间有点会断掉(超过3s)
朴素dij…
错麻了,一直wa6 -> wa34,存一下,到时候再来改
服了,这破精度
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include<climits>
#define IOS ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
using namespace std;
const int maxx = 1e4 + 5;
const int maxn = 1e6 + 5;
#define N 10000100
#define ll long long
#define endl '\n'
const ll mod = 998244353;
#define test printf("--------------------------\n");
#define re(a) memset((a), 0, sizeof((a)))
#define remax(a) memset((a), 0x3f3f3f3f, sizeof((a)))
#define PII pair<int, int>
pair<ll, ll> p[maxn];
double v1, v2;
ll n;
double t[1100][1100]; //每一个点到每一个点的用时
vector<ll> v[maxn];
void dij(int j){
priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> q;
q.push({0, 0});
double dist[1100];
bool vis[1100];
re(vis);
fill(dist, dist + 1100, LLONG_MAX);
dist[0] = 0;
while(!q.empty()){
int now = q.top().second;
q.pop();
if(vis[now])
continue;
vis[now] = true;
for(auto w : v[now]){
if(dist[w] > dist[now] + t[now][w]){
dist[w] = dist[now] + t[now][w];
q.push({dist[w], w});
}
}
}
printf("%f", dist[n + 1]);
}
double timee(int i, int j){//i -> j
ll tem = 1ll * (p[i].first - p[j].first) * 1ll * (p[i].first - p[j].first) + 1ll * (p[i].second - p[j].second) * 1ll * (p[i].second - p[j].second);
double temp = sqrt(tem);//长度
double tt;
if(i == 0 || i == n + 1){//没有加速功能
tt = temp / v1;
}
else {
double te = temp - 3.0 * v2;
if(te > 0) {
tt = 3.0 + te / v1;
}
else
tt = temp / v2;
}
return tt;
}
int main() {
IOS;
cin >> n;
for (int i = 1; i <= n; ++i){
cin >> p[i].first >> p[i].second;
}
cin >> p[0].first >> p[0].second;
cin >> p[n + 1].first >> p[n + 1].second;
cin >> v1 >> v2;
for (int i = 0; i <= n + 1; ++i){
for (int j = 0; j <= n + 1; ++j){
if (i == j)
continue;
t[i][j] = timee(i, j);//i -> j
v[i].push_back(j);
}
}
dij(0);
return 0;
}
L - Candy Machine
犹豫了下不可能这么简单吧果然wa9
又去翻译了题,考虑过一个一个放进去,小的一定可以加在这个子集里,马上推翻
从子集里挑选比子集平均数大的数,题反复没读懂…
这题只有二分+前缀和做法
先贪选取整个集合,再更新,可以证明去掉一个最大数一定可以使整体变小,能选取的数可能会更多;找截取部分大于平均数的下标,算能选多少个
ll a[maxn];
int main() {
IOS;
int n;
cin >> n;
ll sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
sum += a[i];
}
sort(a + 1, a + 1 + n);
ll ans = 0, j = 0;
ll avr = sum / n;
ans = n - (upper_bound(a + 1, a + 1 + n, avr) - (a + 1));
for (int i = n; i > 1; --i) {
sum -= a[i];
avr = sum / (i - 1);
//cout << avr << " ";
j = i - (upper_bound(a + 1, a + i, avr) - (a + 1)) - 1;
//cout << j << endl;
ans = max(ans, j);
}
cout << ans;
return 0;
}
#M - BpbBppbpBB
第一判断:连通图( + 判格子形状),但存在一点问题
一看题解,啊解方程?!
I - Barbecue
觉得应该是先找回文串在哪然后减去回文长度%2判,但是,该去补马拉车了
好厉害,这题用hash处理只需要o(1)
https://www.cnblogs.com/Uninstalllingyi/p/11191045.html
O(1)字符hash板子题
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include<cmath>
#include<stack>
#include<queue>
#define IOS ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
using namespace std;
const int maxx = 1e4 + 5;
const int maxn = 1e6 + 5;
#define N 10000100
#define ll long long
#define endl '\n'
const ll mod = 998244353;
#define test printf("--------------------------\n");
#define re(a) memset((a), 0, sizeof((a)))
#define remax(a) memset((a), 0x3f3f3f3f, sizeof((a)))
#define PII pair<int, int>
vector<int> v;
#define ull unsigned long long
ull p = 13331;
ull hash_a[maxn], hash_b[maxn], power[maxn];
void init(string s, int len){
hash_a[0] = 0, hash_b[0] = 0, power[0] = 1;
for (int i = 1; i <= len; ++i){
hash_a[i] = hash_a[i - 1] * p + (s[i] - 'a');
hash_b[i] = hash_b[i - 1] * p + (s[len - i + 1] - 'a');
power[i] = power[i - 1] * p;
}
}
bool part_judge(int l, int r, int len){
ull ta = hash_a[r] - hash_a[l - 1] * power[r - l + 1];
ull tb = hash_b[len - l + 1] - hash_b[len - r] * power[r - l + 1];
return ta == tb;
}
int main() {
IOS;
// freopen("P1908_6.in","r",stdin);//读入数据
// freopen("P1908.out","w",stdout); //输出数据
int len, q;
cin >> len >> q;
string s;
cin >> s;
s = " " + s;
init(s, len);
for (int i = 1; i <= q; ++i){
int l, r;
cin >> l >> r;
if(part_judge(l, r, len)){
cout << "Budada" << endl;
}
else {
if((r - l + 1) % 2){
cout << "Putata" << endl;
}
else {
cout << "Budada" << endl;
}
}
}
return 0;
}