CCF-CSP认证题解

算法设计老师作业要求,看看能补多少补多少吧

我去年入围选拔赛坐校车去南海校区第一次参加csp

100+70+70=240

计院第一 全校第四,拿了300块奖金

那一场是第23次,排名5%

第25次CCF-CSP认证题解

第一题 未初始化警告

#include<bits/stdc++.h>
using namespace std;
int n,k,a,b,ans;
int vis[100010];
signed main(){
   
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>k;
    vis[0]=1;
    while(k--){
   
        cin>>b>>a;
        if(!vis[a])ans++;
        vis[b]=1;
    }
    cout<<ans;
}

第二题

一开始读错题目了,以为是q>=a&&q<a+b

每一个活动的贡献是a-b+1,a这个区间,弄一下差分就好了

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,k,a[N],b[N],ans,c[N];

signed main(){
   
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
   
        cin>>a[i]>>b[i];
        c[max(a[i]-b[i]+1,1)]+=1;
        c[a[i]+1]-=1;
    }
    for(int i=1;i<N;i++)c[i]+=c[i-1];
    while(m--){
   
        int q;
        cin>>q;
        q+=k;
        cout<<c[q]<<'\n';
        
    }
}

第三题

#include <bits/stdc++.h>
using namespace std;
const int mod = 929, N = 1e5 + 5;
int w, s, k, pre = 1;
string str;
int t[N], tmp[N], g[N], d[N];
int main()
{
   
	cin >> w >> s >> str;
	if (s == -1) k = 0;
	else k = pow(2, s + 1);
	int idx = 0;
	for (char i : str)
	{
   
		if (i >= 'A' && i <= 'Z')
		{
   
			if (pre != 1) t[idx++] = 28; 
			if(pre == 2) t[idx++] = 28;
			t[idx++] = i - 'A';
			pre = 1;
		}
		else if (i >= 'a' && i <= 'z')
		{
   
			if (pre != 2) t[idx++] = 27;
			t[idx++] = i - 'a';
			pre = 2;
		}
		else
		{
   
			if (pre != 3) t[idx++] = 28;
			t[idx++] = i - '0';
			pre = 3;
		}
	}
	if (idx & 1) t[idx++] = 29;
	int len = 0;
	for (; len < idx; len += 2) tmp[len / 2] = t[len] * 30 + t[len + 1];
	len /= 2;
	int sum = len + 1 + k;
	if (sum % w)
		for (int i = 0; i < w - (sum % w); ++i) tmp[len++] = 900;

	int c = -3;
	g[0] = 1;
	for (int i = 1; i <= k; ++i, c = c * 3 % mod)
	{
   
		for (int j = i - 1; j >= 0; j--)
		{
   
			g[j + 1] = (g[j] * c + g[j + 1]) % mod;
		}
	}
	d[0] = len + 1;
	for (int i = 1; i <= len; ++i) d[i] = tmp[i - 1];
	
	for (int i = 0; i <= len; i++)
	{
   
		int x = d[i];
		d[i] = 0;
		for (int j = 1; j <= k; j++)
		{
   
			d[i + j] = (d[i + j] - x * g[j]) % mod;
		}
	}

	cout << len + 1 << '\n';
	for (int i = 0; i < len; ++i) cout << tmp[i] << '\n';
	for (int i = len + 1; i <= len + k; ++i) cout << (-d[i] % mod + mod) % mod << '\n';
	return 0;
}

第四题

这是一道感觉能拿70分的代码,但是不知道错在哪里,听说要用两个堆来维护一下一个可删除堆才是这道题的正解

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
const int N=2e5+10;
struct node{
   
    int a,b,c;
};
unordered_map<int,int>mp[N],t[N];
unordered_set<int>S;
vector<node>day[N];
int vis[N];
int e,cnt;
inline int find(int x){
   
    int ans=0;
    int ans_id=0;
    for(auto &s:mp[x]){
   
        int k=s.first;
        int v=s.second;
        if(v>ans)ans=v,ans_id=k;
        else if(v==ans)ans_id=min(ans_id,k);
    }
    return ans_id;
}
void update(int d){
   
    for(auto t:day[d]){
   
        int a=t.a;
        int b=t.b;
        int c=t.c;
        mp[a][b]-=c,mp[b][a]-=c;
        if(mp[a]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值