进阶训练赛(十)

A-青年歌手大赛-评委会打分

用mx记录最大值,mi记录最小值,all记录和,最后all再减掉mx,mi,再取平均值。

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 0x3f3f3f3f;
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n,t;
    while (cin >> n) {
        vector<int> v(n);
        int mx = -1,mi = inf;
        int all = 0;
        for (int i = 0;i < n;i++) {
            cin >> t;
            mx = max(t,mx);
            mi = min(t,mi);
            all += t;
        }
        all -= mx + mi;
        printf("%.2lf\n", (double)all/(double)(n - 2));
    } 
    return 0;
}

B-I don't want to pay for the Late Jar

每个餐厅有一个得分,通过题意可以得到得分的计算公式score = fi - max(0, ti - s),按每个餐厅的得分进行排序,取最大值。

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int d;
    cin >> d;
    for (int i = 0;i < d;i++) {
        int n, s;
        cin >> n >> s;
        vector<int> v(n);
        for (int ii = 0;ii< n;ii++) {
            int fi, ti;
            cin >> fi >> ti;
            v[ii] = fi - max(0ll, ti - s);
        }
        sort(v.begin(), v.end());
        cout << "Case #" << i + 1 <<":"<< v.back() << "\n";
    }
    return 0;
}

C-Bitset

使用bitset可以快捷地将十进制转化为二进制,再利用to_string()转化为字符串进行操作,去除前导零。

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    bitset<10> b(n);
    string s = b.to_string();
    cout << s.substr(s.find('1')) << "\n";
    return 0;
}

D 2.4.5 度度熊学队列

利用C++ STL deque,实现双端队列。

#include <bits/stdc++.h>
using namespace std;
#define int long long
deque<int> dq[150010];
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n , q;
    while (cin >> n >> q) {
        while (q -- ) {
            int op, u, w, val, v;
            cin >> op;
            if (op == 1) {
                cin >> u >> w >> val;
                if (w) {    // 后面
                    dq[u].push_back(val);
                }
                else {
                    dq[u].push_front(val);
                }
            }
            else if (op == 2) {
                cin >> u >> w;
                if (dq[u].empty()) {
                    cout << "-1\n";
                    continue;
                }
                if (w) {    // 后面
                    cout << dq[u].back() << "\n";
                    dq[u].pop_back();
                }
                else  {
                    cout << dq[u].front() << "\n";
                    dq[u].pop_front();
                }
            }
            else {
                cin >> u >> v >> w;
                if (w) {     // 逆序
                    while (!dq[v].empty()) {
                        dq[u].push_back(dq[v].back());
                        dq[v].pop_back();
                    }
                }
                else {
                    while (!dq[v].empty()) {
                        dq[u].push_front(dq[v].front());
                        dq[v].pop_front();
                    }
                }
            }
        }
    }
    return 0;
}

E-[蓝桥杯2016初赛]密码脱落

参考链接,区间dp,首先将题意转化一下,由于添加字母的本意就是让原本不配当的字母配对,因此添加字母的数量等价于删掉字母的数量,删掉最少的字母使得原串变成镜像串,即求最大回文子序列的长度。

dp[i][j]表示i~j所有回文子序列的长度的最大值。

状态转移方程:

如果s[i] == s[j],即s[i]s[j]是在最长回文子序列中的,则:

dp(i)(j)=dp(i+1)(j1)+2

如果s[i] != s[j],即s[i]s[j]至少有一个不在最长回文子序列中,则:

dp(i)(j)=max{dp(i)(j1),dp(i+1)(j)}

其中,dp[i][j-1]包含了

  • s[i]在,s[j]不在
  • s[i]不在,s[j]也不在

两种情况。dp[i+1][j]包含了

  • s[i]不在,s[j]
  • s[i]不在,s[j]也不在

两种情况。

#include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int)(x.size())
#define int long long
int dp[1010][1010];
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    string s;
    while (cin >> s) {
        for (int i = 0;i < SZ(s);i++) dp[i][i] = 1; // 只有s[i]一个字符,必然是回文序列,长度为1
        for (int len = 2;len <= SZ(s);len++) {
            for (int i = 0;i < SZ(s) + 1 - len;i++) {
                int j = i + len - 1;
                if (s[i] == s[j]) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                }
                else {
                    dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
                }
            }
        }
        cout << SZ(s) - dp[0][SZ(s) - 1] << "\n";
    }
    return 0;
}

F-[蓝桥杯2016初赛]平方怪圈

利用2作为最初始的数,看是否满足,如果不满足就再试试3,一直下去,恰好2满足循环。

#include <bits/stdc++.h>
using namespace std;
#define int long long
map<int,bool> mp;

void get(int i) {
    int t = i;
    if (!mp[i])
        mp[i] = 1;
    else {
        if (i == 1) {
            exit(0);
        }
        else {
            for (auto [a, b] : mp) {
                cout << a << "\n";
            }
            exit(0);
        }
    }
    int res = 0;
    while (t) {
        int tt = t % 10;
        res += tt * tt;
        t /= 10;
    }
    get(res);
}

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    get(2);
    return 0;
}

G-添柴少年

结论:

LCM(a,b)=ab/GCD(a,b)

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a, b;
    cin >>a >> b;
    cout << a * b / __gcd(a,b) << "\n";
    return 0;
}

H-你的就是我的,我的还是我的

可以很明显的发现是加减法,因为1e12的大小不能一个一个地减。

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a, b,k;
    cin >> a >> b >> k;
    if (k >= a) {
        cout << "0 " << max(0ll, b - k + a) << "\n";
    }
    else {
        cout << a - k << " " << b << "\n";
    }
    return 0;
}

I-下一个素数

由于数据大小为1e5,因此可以考虑以下解法:

  • 欧拉筛+二分查找(时间:16ms)
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define SZ(x) (int)(x.size())
vector<int> p;
int vis[10000010];
void ols(int x) {
    for (int i = 2;i <= x;i++) {
        if (!vis[i]) p.push_back(i);
        for (int j = 0;j < SZ(p);j++) {
            if (i * p[j] > x) break;
            vis[i * p[j]] = 1;
            if (i % p[j] == 0) break;
        }
    }
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    ols(t*10);
    cout << *lower_bound(p.begin(), p.end(), t) << "\n";
    return 0;
}
  • 用6的倍数加速找素数(时间:1ms)
#include <bits/stdc++.h>
using namespace std;
#define int long long
bool check(int x) {
    for (int i = 2;i <= sqrt(x);i++) {
        if (x % i == 0) return 0;
    }
    return 1;
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t;
    cin >> t;
    if (t == 2 || t == 3) {
        cout << t << "\n";
    }
    else {
        int x = t / 6;
        for (int i = x;i <= 100010;i ++) {
            int a = i * 6;
            if (a - 1 >= t && check(a - 1)) {
                cout << a - 1 << "\n";
                return 0;
            }
            if (a + 1 >= t && check(a + 1)) {
                cout << a + 1 << "\n";
                return 0;
            }
        }
    }
    return 0;
}

J-60万岁,61浪费

用总分数进行比较,可以避免浮点数。

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, s, f;
    cin >> n >> s >> f;
    int all = 0;
    for (int i = 0;i < n - 1;i++) {
        int t;
        cin >> t;
        all += t;
    }
    if (all + s < n * f) {
        cout << "-1\n";
    }
    else {
        cout << max(n * f - all,0ll) << "\n";
    }
    return 0;
}

K-上数论课

求a和b的gcd,然后求出gcd的所有约数中有多少个素数,再加1,感觉比较正确。

由于a和b的最大公约数为gcd,所以所有的公共因子就是gcd的因子

// #include <bits/stdc++.h>
using namespace std;
#define SZ(x) (int)(x.size())
#define int long long
bool check(int x) {
    for (int i = 2;i <= sqrt(x);i++) {
        if (x % i == 0) return 0;
    }
    return 1;
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a, b;
    cin >> a >> b;
    int ans = 0;
    int g = __gcd(a,b);
    for (int i = 2;i <= sqrt(g);i++) {
        if (g % i == 0) {
            if (check(i)) ans++;
            while(g % i == 0) {
                g /= i;
            }
        }
    }
    if (g != 1 && check(g)) ans++;
    cout << ++ans << "\n";
    return 0;
}

L-宝藏开箱者

不太会,看了题解点我懂了!

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf = 0x3f3f3f3f;
int dp[5000];
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    for (int i = 0;i <= 4500;i++) dp[i] = inf;
    dp[0] = 0;
    vector<vector<int>> keys (m, vector<int> ());
    vector<int> price(m,0);
    for (int i = 0;i < m;i++) {
        int cnt;
        cin >> price[i] >> cnt;
        for (int k = 0; k < cnt;k++) {
            int t;
            cin >> t;
            t--;
            keys[i].push_back(t);
        }
    }
    for (int i = 0;i < m;i++) {
        int THIS = 0;
        for (auto x : keys[i]) {
            THIS |= (1 << x);
        }
        for (int st = 0;st < (1 << n);st++) {
            int THAT = THIS | st;
            dp[THAT] = min(dp[THAT], dp[st] + price[i]);
        }
    }
    if (dp[(1 << n) - 1] == inf) cout << "-1\n";
    else cout << dp[(1 << n) - 1] << "\n";
    return 0;
}

M-奇异吃牌者

题解点我,数学公式的推导,不是很懂...

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;

int a[300010];
int c[300010];
int d[300010];

int main(){
    int n;
    cin >> n;
    for (int i = 1;i <= n; i++){
        int x;
        cd(x);
        a[x]++;
        c[a[x]]++;
    }
    d[0] = 0;
    for (int i = 1; i <= n; i++) 
        d[i] = d[i - 1] + c[i];
    for (int k = 1;k <= n; k++) {
        int ans = 0;
        int left = 0, right = n;
        while (left <= right) {
            int mid = (left + right) / 2;
            if((ll)k * mid <= d[mid]) {
                left = mid + 1;
                ans = max(ans, mid);
            }
            else{
                right = mid - 1;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}
posted @   Uzhia  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示