Educational Codeforces Round 157 (Rated for Div. 2)

在这里插入图片描述

Educational Codeforces Round 157 (Rated for Div. 2)

Dashboard - Educational Codeforces Round 157 (Rated for Div. 2) - Codeforces

A. Treasure Chest

题意:在一条OX坐标轴上,箱子在x处,钥匙在y处,箱子最多可以移动k秒,初始在0点处,一秒移动一个单位,最短时间打开箱子

思路:箱子比钥匙远,拿着钥匙找箱子;箱子比钥匙远,若能把箱子移动到钥匙,则一路带着箱子找钥匙,否则把箱子移动到最大距离,然后跑来回拿钥匙开箱子

AC code:

#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;

typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 5e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, x, y, k;

int gcd(int a, int b){
    if(b) while((a %= b) && (b %= a));
    return a + b;
}

int main(){
    fast();
    
    T = 1;
    cin >> T;
    while(T --){
        cin >> x >> y >> k;
        int ans = 0;
        if(x >= y) ans = x;
        else{
            if(y - x <= k) ans = y;
            else{
                ans = x + k;
                ans += 2 * (y - (x + k));
            }
        }
        cout << ans << endl;
    }
    return 0;
}

B. Points and Minimum Distance

题意:把2*n个点分成n个坐标,使n个坐标相连的距离最小

思路:排序,双指针分别指向首尾,依次作为xy坐标,保证|x1 - x2| + |y1 - y2| 最小

AC code:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;

typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 5e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, m;
int a[N];

int gcd(int a, int b){
    if(b) while((a %= b) && (b %= a));
    return a + b;
}

signed main(){
    fast();
    
    T = 1;
    cin >> T;
    while(T --){
        cin >> n;
        for(int i = 1; i <= 2 * n; i ++)
            cin >> a[i];
        sort(a + 1, a + 2 * n + 1);

        vector<PII> ans;
        int l = 1, r = 2 * n;
        while(l <= n){
            ans.push_back({a[l], a[r]});
            l ++, r --;
        }
        int sum = 0;
        for(int i = 1; i < n; i ++){
            sum += abs(ans[i].first - ans[i - 1].first) + abs(ans[i].second - ans[i - 1].second);
        }
        cout << sum << endl;
        for(auto i : ans){
            cout << i.first << " " << i.second << endl;
        }
    }
    return 0;
}

C. Torn Lucky Ticket

题意: 给出n个由数字组成字符串,定义当一个字符串前缀数字和等于后缀数字和时该字符串为一个幸运字符串,在n个字符串中选择si和sj串进行连接组成新的字符串(i可以等于j,且i+j与j+i为两种),有多少对可以组成幸运字符串

思路:若两个字符串可以组成幸运字符串,则有两种连接可能:

  • 首尾相连,两字符串长度以及数字和相同
    • 在开始时便用二维map记录每个字符串的长度已经数字和,然后累加记录的情况
  • 以前缀字符串或后缀字符串中的某点为分界点,组成的新字符串符合要求,因为字符串最大为5,所以可以枚举分界点进行组合
    • 从前往后连接,当分界点的长度大于当前字符串一半时,寻找是否有长度与数字和符合的后缀字符串
    • 从后往前连接,将所有字符串反转,重复上述过程

AC code:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;

typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 5e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, m;
vector<int> cnt(N, 0);
vector<string> s(N);
map<int, int> mp[M];

int gcd(int a, int b){
    if(b) while((a %= b) && (b %= a));
    return a + b;
}

signed main(){
    fast();
    
    T = 1;
    //cin >> T;
    while(T --){
        cin >> n;
        for(int i = 1; i <= n; i ++){
            cin >> s[i];
            for(auto j : s[i]) cnt[i] += j - '0';

            mp[s[i].size()][cnt[i]] ++;
        }
        int ans = 0, casual = 0;
        for(int i = 1; i <= n; i ++)//字符串长度与数字和相同的串
            ans += mp[s[i].size()][cnt[i]];
        for(int i = 1; i <= n; i ++){//从前往后连接
            casual = 0;
            for(int j = 0; j < s[i].size() - 1; j ++){
                casual += s[i][j] - '0';//枚举前缀分界点长度与大小
                if(j + 1 > s[i].size() - (j + 1))
                    ans += mp[j + 1 - (s[i].size() - (j + 1))][casual - (cnt[i] - casual)];//寻找对应后缀字符串
            }
        }
        for(int i = 1; i <= n; i ++) reverse(s[i].begin(), s[i].end());//反转字符串,反向连接
        for(int i = 1; i <= n; i ++){//重复枚举寻找过程
            casual = 0;
            for(int j = 0; j < s[i].size() - 1; j ++){
                casual += s[i][j] - '0';
                if(j + 1 > s[i].size() - (j + 1))
                    ans += mp[j + 1 - (s[i].size() - (j + 1))][casual - (cnt[i] - casual)];
            }
        }
        cout << ans << endl;
    }
    return 0;
}
/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| ^_^ |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         佛祖保佑AC,永无bug缠身       
*/

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值