The 19th Zhejiang Provincial Collegiate Programming Contest 2022浙江省赛 (A/B/C/G/L/I)

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;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值