2024年8月24日 个人练习总结

T1 隔离

T384651 隔离 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 内部题

题目大意

给出一个数组,将一个数按照数组顺序不断增加,加一次需要另外增加400,若一次累计增加超过240,则要另外加10080,求累加后数字最小为几

思路

贪心思路,首先尽可能少加,如果超过240了则要计算一直加到最后来的便宜还是悬崖勒马来的便宜。

代码

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int N = 1005;
int n, flag, ans, sum[N];

int mian(){
	cin >> n;
	for(int i=1; i<=n; i++){
		cin >> sum[i];
		if (sum[i] > 240) flag = 1;
		sum[i] += sum[i - 1];
	}
	if(flag == 0){
		int l = 0;
		for(int i = 1; i < n; i++){
			if(sum[i]-sum[l] >= 240){
				l = i-1;
				ans += 400;
			}
		}
		ans = min(ans, 10080);
	}
    else ans = 10080;
	ans += sum[n] + 400;  
    cout << ans << endl;
}

//故意少写了两个符号

T2 循环移位

T384652 循环移位 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 内部题

题目大意

有一个可以不断往左边移的数组,求最大的回文串。

思路

首先写出来一个非常简单的判断最大回文串的代码,这点不加赘述,是个人都会。接下来有两种做法,一种是不断往左边移,遍历所有可能,复杂度O(n^{3}),期望得分40pt,实际应该会高一点。

第二种是我的做法,首先复制一个字符串,例如输入aab,则复制一下变成aabaab,这个时候对这个大的字符串求最大回文串,答案是5,显然不是正确答案(3),怎么办呢?注意这个最大的回文串aabaa,我们对于这个串可以发现中间的aba明显符合要求,若这个的长度的奇偶性与n的奇偶性相同,则答案就是n,否则答案为n-1。期望ac,实际ac。

代码

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;

int cnt(const string &s){
    int n = s.size();
    if(n == 0) return 0;
    int code;
    int by;
    int waterpail;
    vector<vector<bool>> dp(n, vector<bool>(n, false));
    int c = 1;

    for(int i=0; i<n; i++){
        dp[i][i] = true;
    }
    int EAS,on,top;
    for(int i=0; i<n-1; i++){
        if(s[i] == s[i + 1]){
            dp[i][i + 1] = true;
            c = 2;
        }
    }

    for(int len=3; len<=n; len++){
        for(int i=0; i<=n-len; i++){
            int j = i + len - 1;
            if(s[i] == s[j] && dp[i + 1][j - 1]){
                dp[i][j] = true;
                if(len>c){
                    c = len;
                }
            }
        }
    }

    return c;
}

int main(){
    int n;
    cin >> n;
    string s;
    cin >> s;
    string ss = s+s;
    int ans = cnt(ss);
    if(ans > n){
    	if((ans+n)&2){
    		cout << n-1 << endl;
		}
		else{
			cout << n << endl;
		}
	}
    else{
    	cout << ans << endl;
	}
    
}

T3

T384653 武器获取 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 内部题

题目大意

难以概括,见题。

思路

我的做法比较诡异,不说了,0pt

题解强,我看题解,对于每一个区间都进行一次计数,统计每种武器的出现次数,如果出现次数达标,则收获这个武器。输出答案时进行组合数的判定即可。时间n方,期望40pt。

100pt题解难以理解,是通过优化计数进行剪枝吗?

代码

40pt

while(m--){
	cin >> l >> r >> k;
	s = 0, ans = 0;
	for(int i = 0; i <= 100005; i++)
		b[i] = 0;
	for(int i = l; i <= r; i++)
		if(a[i] <= 100005){
			b[a[i]]++;
			if(b[a[i]] == a[i]){
				s++;
			}
		}
	if(s >= k){
		ans = 1;
		for(int i = 0; i < k; i++){
			ans *= s - i;
		}
		for(int i = 1; i <= k; i++){
			ans /= i;
		}
	}
	cout << ans << endl;
}

100pt

long long C(int n,int m) {
	if (n < m) return 0;
	if (m == 1) return n;
	else if (m == 2) return n * (n - 1) / 2;
	else if (m == 3) return 1ll * n * (n - 1) * (n - 2) / 6;
	else return 1ll * n * (n - 1) * (n - 2) * (n - 3) / 24;
}
cin >> m;
	while (m--) {
		cin >> l >> r >> k;
		int ans = 0;
		for (int i = 1; i <= tot; i++) { // 枚举每一种武器
			if (pre[i][r] - pre[i][l - 1] >= b[i]) ans++; // 出现次数符合要求,则 ans++ 更新武器数量
		}
		cout << C(ans, k) << endl;
	}
for (int i = 1; i <= n; i++) { // 读入部分,统计每种武器的出现次数
	cin >> a[i];
	if (a[i] <= n) cnt[a[i]]++; // 注意这个 if,谨防 RE
}
for (int i = 1; i <= n; i++) {
	if (cnt[i] >= i) { // 这个 if 只会进入根号 n 次
		b[++tot] = i; // 记录这种武器需要的次数
		for (int j = 1; j <= n; j++)  // 统计前缀和
			pre[tot][j] += pre[tot][j - 1] + (a[j] == i);
	}
}
我没有拼接,但是看得懂

T4

T384655 最大公约数的期望 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目大意

考察期望,见原题

思路

骗分之神能骗到20pt,部分分之神能用快速幂拿到40pt,而题解之神就不同,用我看不懂的方法拿到了100pt。

代码

20pt

#include<bits/stdc++.h>
#define endl '\n'
using namespace std;

int main(){
	int n;
	cin >> n;
	vector<int> a(n+1);
	for(int i=1; i<=n; i++){
		cin >> a[i];
	}
	cout << __gcd(a[0],a[1]) << endl;
}
我防伪都不想做,要是这都写不出来这辈子有了

40pt

cin >> n;
numk = (n * (n - 1) / 2) % mod; // 算出 C(n,2)
inv = q_pow(numk, mod - 2); // 用快速幂算出逆元,这个是期望的分母
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) for (int j =  i + 1; j <= n; j++) ans += __gcd(a[i], a[j]); // 两重循环计算所有 gcd 之和,也就是期望的分母
cout << ans * inv % mod; // 分子乘以分母的逆元就是答案

我这辈子有了,这么简单的我做不出来 LLLL

100pt

不放代码了,看不懂就尊重代码

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值