• 牛客寒假算法基础集训营2 解题报告


    假算法基础集训营名副其实。

    只会5题的我真是菜爆了qwq。

    所以写完5题还剩下1h就来写题解是不是没救了啊

    这场的题解按难度排序...(其实就是我过题的顺序)

    顺序是DJGHC。

    赛后吐槽:

    A到底卡什么啊
    B这么毒瘤的大模拟咋写啊
    我居然还有前50,手速果然重要
    想中牛可乐qwq

    D

    做法:模拟

    按题意模拟...

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define N 100010
    int n;
    int a[N];
    ll ans = 0;
     
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) {scanf("%d", &a[i]); if(a[i] < 60) ans += 400;}
        printf("%lld
    ", ans);
    }
    

    J

    做法:贪心

    因为可以把复习时间拆开,所以直接按开始考试的时间排序一波。
    然后假装我们可以篡改考试时间,复习完了就让他考试(也就是+2h)
    每次考试前看复习时间有没有超过考试的开始时间就好了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    #define N 100010
    int n;
    struct Node {
        ll a, b;
    }a[N];
     
    bool cmp(Node a, Node b) {
        return a.b < b.b;
    }
     
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) scanf("%lld", &a[i].a);
        for(int i = 1; i <= n; ++i) scanf("%lld", &a[i].b);
        sort(a + 1, a + n + 1, cmp);
        ll cnt = 0;
        for(int i = 1; i <= n; ++i) {
            cnt += a[i].a;
            if(cnt > a[i].b) return puts("NO"), 0;
            cnt += 2;
       //     printf("%lld
    ", cnt);
        }
        puts("YES");
        return 0;
    }
    

    G

    做法:dp

    不知道这题的std是啥...赛后看看。
    其实这题有原题的...原题:LGOJP2758
    其实就是按原题那个做法搞一波,然后看看dp出来的结果会不会小于等于2即可

    (f[i][j])表示前(i)个字符变成结果串的前(j)个字符要变换多少次。
    那么删除即为(f[i][j]=min(f[i-1][j]+1))
    插入即为(f[i][j]=min(f[i][j-1]+1))
    替换即为(f[i][j]=min(f[i-1][j-1]+1))
    初始化边界为(f[0][i]=f[i][0]=i)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define N 2010
    int f[N][N];
    char s[N], t[N];
    //第一个串到i,第二个串到j最小操作次数 
    
    int main() {
    	scanf("%s%s", s + 1, t + 1);
    	int n = strlen(s + 1), m = strlen(t + 1);
    	for(int i = 1; i <= n; ++i) f[i][0] = i;
    	for(int i = 1; i <= m; ++i) f[0][i] = i;
    	for(int i = 1; i <= n; ++i) {
    		for(int j = 1; j <= m; ++j) {
    			if(s[i] == t[j]) {f[i][j] = f[i - 1][j - 1]; continue;} //正好相等就不管 
    			f[i][j] = min(min(f[i - 1][j], f[i][j - 1]), f[i - 1][j - 1]) + 1; 
    			//删除,插入,替换 
    		}
    	}
    	if(f[n][m] <= 2) puts("YES");
    	else puts("NO");
    }
    

    至于这题的LCS做法错在哪里?
    事实上就是因为LCS没办法考虑位置。
    这里给一组hack数据:
    abxyabcd
    ababxycd
    实际上是no但是LCS做法会输出yes

    H

    做法:数论

    考虑怎么让一个数有超过10个因数,显然只要有4个质因子就够了。
    然后任意两个数都互质这意味着所有数没有相同的质因子。
    而题目给的因数是(x*y)的,这意味着每个数只要有两个质因子就够了。
    于是我们预处理出前4000个素数,每两个丢在一起,让他们组成一个数。
    注意要尽量平均不然会超过题目的要求。如:第1个和第4000个组合在一起。
    那么这题就做完了。
    我忘记把freopen删掉居然被罚时了QAQ
    (代码里到6000跳是没有必要的不过懒得改了)

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N = 1e8 + 10;
    bool vis[N];
    ll p[8000], ans[3000];
    int n; 
    
    int main() {
    //	freopen("ans.out", "w", stdout);
    	int cnt = 0;
    	for(ll i = 2; i <= (ll)1e8; ++i) {
    		if(cnt > 6000) break;
    		if(!vis[i]) p[++cnt] = i;
    		for(int j = 1; j <= cnt && i * p[j] <= (ll)1e8; ++j) {
    			vis[i * p[j]] = 1;
    			if(i % p[j] == 0) break;
    		}
    	}
    	for(int i = 1; i <= 2000; ++i) ans[i] = 1;
    	for(int i = 1; i <= 2000; ++i) {
    		ans[i] *= p[i];
    	}
    	int qwq = 2000;
    	for(int i = 2000; i; --i) {
    		ans[i] *= p[++qwq];
    	}
    	for(int i = 1; i <= 2000; ++i) printf("%lld ", ans[i]);
    }
    

    C

    做法:数论(找规律)

    其实这个是我弃赛了之后水QQ被一个大佬点醒了这题的思路,并且研究了一波样例解释才会的。
    我写这种脑洞题是真的菜。

    1=1
    2=2
    3=1+2
    4=6-2
    5=6-1
    6=6
    7=6+1
    8=6+2
    9=6+2+1
    10=11-1
    11=11
    12=11+1
    13=11+2
    14=11+2+1
    15=11+6-2
    16=11+6-1
    17=11+6
    18=11+6+1
    19=11+6+2
    20=11+6+2+1

    并且采用人脑+草稿纸将它继续推下去
    研究一下这个可能会发现一些奇奇怪怪的规律
    (3^0,3^1,3^2...)这个数列的前缀和中的数会影响答案
    (即(1,4,13,40...)
    即1的答案是1,2-3的答案是2,4-12的答案是3,13-39的答案是4
    没人提醒完全想不到这个结论(我好菜啊)
    数论还是要加强qwq
    证明我是不会证的,这个结论就是猜出来的...证明之后放std的证明吧

    官方题解证明:

    什么?你说(n<=10^{1000})
    人生苦短我用python

    a = 0
    b = 0
    c = 1
    n = int(input())
    while b < n :
        a = a + 1
        b = b + c
        c = c * 3
    print(a)
    

    其他题真的写不动了,只能靠手速混在第一页混日子过。

    官方题解

  • 相关阅读:
    Echarts数据可视化grid直角坐标系(xAxis、yAxis)
    Cannot find module '@babel/plugin-proposal-class-properties'
    git 基本操作
    React报错:Laravel React-Router browserHistory 刷新子页面报错404
    php报错:Notice: iconv(): Wrong charset, conversion from `GBK' to `UTF8' is not allowed
    Larval报错:后台上传图片,storage目录也有相应的图片,但前台访问不到图片。
    Laravel报错:1071 Specified key was too long; max key length is 1000 bytes
    thinkcmf报错:fileowner(): stat failed for /sys
    vbox虚拟机复制&&虚拟机指定静态IP
    thinkcmf在万网上部署
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10314957.html
Copyright © 2020-2023  润新知