ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SZUACM2022招新积分赛Day2 总结

2022-05-23 10:03:16  阅读:146  来源: 互联网

标签:招新 const cout int res Day2 long SZUACM2022 using


SZUACM2022招新积分赛Day2 总结

很难过但还是来补题
这次给一些题目添上了图解

题目

下午

晚上

补题

A.Gym 103438A

一种非常巧妙的转移:
从后往前扫,考虑前缀
小:出现多种前缀 f[i - 1] = n - i //长度代表可能
同:相当于一个桥,过渡过去 f[i] = f[i + 1]

#include <bits/stdc++.h>

using namespace std;
const int N = 2e5 + 5;
long long f[N], ans;

int main  () {
    int n;
    cin >> n;
    string s, t;
    cin >> s >> t;
    for (int i = n - 1; i >= 0; i --) {
        if (s[i] > t[i])
            continue;
        if (s[i] < t[i])
            f[i] = n - i;
        if (s[i] == t[i])
            f[i] = f[i + 1];
        ans += f[i];
    }
    cout << ans;      
}
//大佬的666dp
//从后往前扫,考虑前缀
//小:出现多种前缀 f[i - 1] = n - i //长度代表可能
//同:相当于一个桥,过渡过去 f[i] = f[i + 1]


//同:往后找小  
//小:往后找小/同
//大:skip
//dp

//先找到第一个同一位置上s比t小的,然后
//往前:相同的可以统计进去
//往后:
//注意,一旦不符合条件就break,因为字串要连续

B. Gym 103438N

在那里模拟了半天,其实差的不多了
最后想复杂了,反而还绕路了
主题应该是当前b[i],我反过来传递成了res,所以假了

#include <bits/stdc++.h>
#define int long long 

using namespace std;
const int N = 2e5 + 5;

int n, op;
int a[N], b[N];

signed main () {
    cin >> n;
    for (int i = 0; i <= n; i ++)
        cin >> a[i];
    for (int i = 0; i <= n; i ++)
        cin >> b[i];
    
    for (int i = n; i > 0; i --) {
        int res = b[i] - a[i];
        if (res < 0)
            continue; //不用传递了
        b[i] -= res;
        res = (res + 1) / 2, b[i - 1] += res;
        op += res;
    }

    for (int i = 0; i <= n; i ++)
        if (b[i] > a[i]) {
            op = -1;
            break;
        }
        
    cout << op << endl;
}
//模拟
//每传到下一级,op+=res,res*=2
//从后往前看需求 (ci+1)/2

//n+1种尺寸:A0,A1,...An
//现有:a0个A0,a1个A1...
//至少要有:b0个A0,b1个A1...
//op:A_i->2*A_{i + 1}

//先保证前面的,再往后拆分

//eg
//1006+498+244+10

挺可惜的,逻辑还是理的不太清楚

C. CodeForces 1672A

简单博弈,总次数为偶数就后手胜

#include <bits/stdc++.h>

using namespace std;
const int N = 55;
int n;
int a[N];

void solve () {
    int op=  0;
    cin >> n;
    for (int i= 1; i <= n; i  ++)   {
        int x;
        cin >> x;
        op += x - 1;
    }

    if (op % 2 == 0)
        cout << "maomao90" << endl;
    else
        cout << "errorgorn" << endl;
}

int main () {
    int t;
    cin >> t;
    while (t --) {
        solve ();
    }
}

实在惭愧,这是原题,然而我忘了。。。

A. 51Nod 1001

签到题,却WA了三次。。
直接i j 两头找就行了

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 50005;
int n, k;
int a[N];

signed main () {
    cin >> k >> n;
    for (int i = 1; i <= n; i ++)
        cin >> a[i];

    sort (a + 1, a + n + 1);
    bool flag = false;

    for (int i = 1, j = n; i < j; ) {
        if (a[i] + a[j] == k) {
            flag = true;
            cout << a[i] << ' ' << a[j] << endl;
            i ++, j --;
        }
        if (a[i] + a[j] < k)
            i ++;
        if (a[i] + a[j] > k)
            j --;
        
    }

    if (!flag)
        cout << "No Solution" << endl;
}
//-4 -3 -2 -1  

B.51Nod - 1105

二分

注意细节,详见代码注释

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 50005;

ll a[N], b[N];
int n, k;

int check (ll x) {
    int cnt = 0, j = n;
    for (int i = 1; i <= n; i ++) {
        while (a[i] * b[j] > x)
            j --;
        cnt += n - j; //因为最后再减了一次,所以免去那个+1
    }
    return cnt;
}

int main () {
    scanf ("%d%d", &n, &k);
    for (int i = 1; i <= n; i ++)
        scanf ("%lld%lld", &a[i], &b[i]);

    sort (a + 1, a + n + 1);
    sort (b + 1, b + n + 1);

    ll l = a[1] * b[1], r = a[n] * b[n];
    while (l < r) {
        ll mid = l + r >> 1;
        if (check (mid) < k)
            r = mid;
        else
            l = mid + 1;

    }
    printf ("%lld", r);
}
//。。。就是二分

//再优化:固定一个,枚举另一个
//若满足,则中间一整段都满足
//画个图

//若a[i]*b[j]>x,则b[j]之后所有b[i]也必定满足a[i]*b[j]
//长度为n-j+1(因为j在往回跳,所以最终为n-j)

E. Gym 102992K
构造,由重要性质\(gcd(i, i+1)=1\)可以想到整体偏移来构造。
具体如下:

得Code:

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 5;
int n, k;

int main () {
    cin >> n >> k;
    if (k == 0 ) {
        cout << -1;
        return 0;
    }

    int st = 2;
    for (int i = 1; i <= n; i ++) {
        if (i == k)
            cout << 1;
        else
            cout << st ++;
        if (i != n)
            cout << ' ';
    }

}
//注意一个重要性质gcd(i,i+1)=1
//所以构造方法为把1放在k位置上,
//然后以此为分界线在此之前的前移,后面的不变

//行末不能有空格!!!!!

标签:招新,const,cout,int,res,Day2,long,SZUACM2022,using
来源: https://www.cnblogs.com/CTing/p/16299603.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有