Codeforces Round #847 (Div. 3) 【VP】

A. Polycarp and the Day of Pi

题意:给出字符串,让字符串与圆周率的前30位进行比对,输出字符串与圆周率正确匹配的字符数,字符串没有小数点

思路:设定const变量字符串,然后对输入字符串字符进行一一比对,并不断更新匹配到的字符长度,直到字符不相等或者到达字符串结尾,输出匹配到的长度

派的前30位题目已给出,字符串不超过30位

#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <unordered_set>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvll;
typedef vector<char> vc;

#define INT_MAX pow(2, 31) - 1
#define INT_MIN -pow(2, 31)

const string s = "314159265358979323846264338327";
int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int N;
    cin >> N;
    while (N--){
        string a;
        cin >> a;
        int rst = 0;
        for (int i = 0; i < a.size(); ++i){
            if (a[i] != s[i]){
                break;
            }
            rst += 1;
        }
        cout << rst << endl;
    }
    return 0;
}

B. Taisia and Dice

题意:给定数字n和r,将r分解成n个数并且每个数不超过6,题目保证每个输入示例有输出。

思路:边界情况是n个数都为1或者n个数都为6。于是可以先建立一个长度为n的数组,然后依次对数组中的数加1,直到该数组的和为r,因为题目保证一定有答案,所以数组元素一定不会超过6。

#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <unordered_set>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvll;
typedef vector<char> vc;

#define INT_MAX pow(2, 31) - 1
#define INT_MIN -pow(2, 31)


int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int N;
    cin >> N;
    while (N--){
        int n, s, r;
        cin >> n >> s >> r;
        cout << s - r << " " ;
        n -= 1;
        vi a(n, 1);
        int sum = n;
        for (int i = 0; sum < r; ++i){
            a[i % n] += 1;
            sum += 1;
        }
        for (auto x : a){cout << x << " ";}
        cout << endl;
    }
    return 0;
}

总结:一开始看到这个题目的时候想到的是将将r平均分配给n个数,然后总和如果不够r再网上补,但是发现如果采用这种建立规则的编程方式,会出现很多特殊情况,于是只能采用这种暴力破解的方法。

C. Premutation

题意:感觉题目应该是permutation。 有一个原始数组,长度为n,并且是乱序的permutation数组。现给出n个输入,每个输入中将去除原始数组中任意一位的元素,并且保证每个输入都不重复。根据这些输入推出原始数组。

思路:题目给出的输入中,每个输入都是缺少了一位,那么如果丢失的是起始位,或者末位,就只需要将该输入的起始位跟末位补上即可。而对于起始位跟末位而言,输入的示例中出现的次数一定超过1次,而且只有一个数字符合条件,那么只要找出输入示例中的这个位,然后再标记输入中起始位不是首位的情况,将起始位跟这个输入输出即是答案。

#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <unordered_set>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvll;
typedef vector<char> vc;

#define INT_MAX pow(2, 31) - 1
#define INT_MIN -pow(2, 31)


int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int N;
    cin >> N;
    while (N--){
        int n;
        cin >> n;
        vvi a(n, vi(n - 1));
        set<int> sett;
        int first_num;
        for (int i = 0; i < n; ++i){
            for (int j = 0; j < n - 1; ++j){
                cin >> a[i][j];
                if (j == 0){
                    if (sett.count(a[i][j])){first_num = a[i][j];}
                    sett.insert(a[i][j]);
                }
            }
        }
        for (int i = 0; i < n; ++i){
            if (a[i][0] != first_num){
                cout << first_num << " ";
                for (int j = 0; j < n - 1; ++j){ cout << a[i][j] << " \n"[j == n - 2];}
            }
        }

    }
    return 0;
}

总结:做题太少,一时半会找不到思路。一开始想的是将每个输入进行比对,确定出每个数所在的位,但是工程量有点大,而且中间的缺失位前后次序不好确定。然后想到如果只丢失起始位的话,其他的位是有序的,而第一位的数字很好确定。

D. Matryoshkas

题意:给定一个数组,数组中存在很多数字,将这些数字串成串,在串尽可能少的情况下将所有数字都包含进去。每个串相邻的数字差值为1,输出最少串的数量。

思路:用有序的map存储每个数字出现的次数,如果当前数字x出现的次数为y次,且数字x-1出现的次数为z次,那么数字x可以生成max(0, y-z)个新的串。

#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <string>
#include <cmath>
#include <algorithm>
#include <stack>
#include <unordered_set>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvll;
typedef vector<char> vc;

#define INT_MAX pow(2, 31) - 1
#define INT_MIN -pow(2, 31)


int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int N;
    cin >> N;
    while (N--) {
        int n, rst = 0;
        cin >> n;
        map<int, int> mapp;
        for (int i = 0; i < n; ++i){
            int tmp;
            cin >> tmp;
            mapp[tmp] += 1;
        }
        for (auto[x, y] : mapp){
            rst += max(0, y - mapp[x - 1]);
        }
        cout << rst << endl;
    }
    return 0;
}

总结:该题目很搞,一开始想到的解决方法是利用哈希表存储数字区间,如果新加入的数字可以并到区间中,那么将这个区间扩大,最后保留的区间数就是串的数,结果发现在制定规则的过程中有一些不可控因素,然后网上借鉴大佬们的方法解出来的题目。该题目的tag有数据结构跟贪心算法,数据结构的话可能就是涉及哈希map相关的知识,贪心的话应该就是在遍历map的时候串的选择策略以及对最终串的数量的影响,是个启发很大的题目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值