ccf-csp:202112

篇幅关系把2021年12月份的发在一篇博客里了

这一次csp拿分情况100+100+40+25+36,最后一题正常暴力应该是拿12分,于是乎我又针对特殊情况暴力了六个点,一共过了9个点拿了36(有点不值~~~)

1.序列查询

话不多说代码如下:

#include <iostream>

using namespace std;

int main()
{
    int n,N;
    cin>>n>>N;
    int sum=0;
    int a[n];
    cin>>a[0];
    for(int i=1;i<n;i++)
    {
        cin>>a[i];
        sum+=(a[i]-a[i-1])*i;
    }
    sum+=(N-a[n-1])*n;
    cout <<sum << endl;
    return 0;
}

2.序列查询新解

#include<iostream>
using namespace std;
long long ans = 0;
const int N=1e5+10;
int cnt;
int i = 0, j = 0;
int a[N];
int b[N];
int main()
{
	int n, N;
	cin >> n >> N;
	for (int i = 1; i <= n; i++) cin >> a[i];
	a[n + 1] = N;
	int k = N / (n + 1);
	for (cnt = 1; cnt * k < N;cnt++) b[cnt] = cnt * k;
	b[cnt++] = N;
	while (i < n+1 || j < cnt-1)
	{
		if (a[i] == b[j])
		{
			ans += (min(a[i + 1], b[j + 1]) - a[i]) * abs(i - j);
			i++, j++;
		}
		else if (a[i] < b[j])
		{
			ans += (min(a[i + 1], b[j]) - a[i]) * abs(j - 1 - i);
			i++;
		}
		else
		{
			ans += (min(b[j + 1], a[i]) - b[j]) * abs(i - 1 - j);
			j++;
		}
	}
	cout << ans;
	return 0;
}

 3.登机牌条码

#include <iostream>
#include <string>

using namespace std;

int w,s,cnt=0;
string str;
int a[1000];
int main()
{
    cin>>w>>s;
    cin>>str;
    for(int i=0;i<str.size();i++)
    {
        int b=str[i]-'0';
        if(str[i]-'0'<17)//"0-9"
        {
            if(i==0||i!=0&&str[i-1]>='A')
                a[cnt++]=28;
            a[cnt++]=b;
        }
        else if(str[i]<='Z'&&str[i]>='A') //"A-Z"
        {
            if(i>0&&str[i-1]>='a') a[cnt++]=28;
            if(i>0&&(str[i-1]>='a'||str[i-1]<'A')) a[cnt++]=28;
            a[cnt++]=b-17;
        }
        else
        {
            if(i==0||i!=0&&str[i-1]<'a')
                a[cnt++]=27;
            a[cnt++]=b-49;
        }

        //a=49 A=17
    }
    if(cnt%2) a[cnt++]=29;
    int siz=cnt/2+1;
    int temp=(cnt/2+1)%w;
    if(temp!=0)
        siz+=(w-temp);
    cout<<siz<<endl;
    for(int i=1;i<siz;i++)
    {
        if(i>cnt/2)
            cout<<900<<endl;
        else
            cout<<(a[(i-1)*2]*30+a[(i-1)*2+1])<<endl;
    }

    return 0;
}

 4.磁盘文件操作

#include <iostream>

using namespace std;
const int N=1e8;
int mem[N],id[N],fid[N];//依次为磁盘i所存储的内容,占用磁盘i程序的编号,占用磁盘i程序的前编号
int n,m,k;
int d,l,r,x;
void func0()
{
    cin>>d>>l>>r>>x;
    int i=l;
    for( ;i<=r;i++)
    {
        if(!id[i]||id[i]==d)
        {
            id[i]=d,mem[i]=x;
        }
        else
        {    if(i==l) i=0;
             break;
        }
    }
    cout<<--i<<endl;;
}
void func1()
{
    cin>>d>>l>>r;
    int i=l;
    for( ;i<=r;i++)
    {
        if(id[i]!=d)
        {
            cout<<"FAIL"<<endl;
            return;
        }
    }
    fill(id+l,id+r+1,0);
    fill(fid+l,fid+r+1,d);
    cout<<"OK"<<endl;
}
void func2()
{
    cin>>d>>l>>r;
    int i=l;
    for( ;i<=r;i++)
    {
        if(fid[i]!=d||id[i])
        {
            cout<<"FAIL"<<endl;
            return;
        }
    }
    fill(id+l,id+r+1,d);
    cout<<"OK"<<endl;
}
void func3()
{
    cin>>d;
    if(id[d])
        cout<<id[d]<<" "<<mem[d]<<endl;
    else
        cout<<"0 0"<<endl;
}
int main()
{
    cin>>n>>m>>k;
    while(k--)
    {
        int op;
        cin>>op;
        if(op==0)
           func0();
        else if(op==1)
           func1();
        else if(op==2)
           func2();
        else
           func3();
    }
    return 0;
}

5.极差路径 

#include <iostream>
#include <vector>

using namespace std;
const int N=5e5+10;
vector<int>adj[N];
int n,k1,k2,minn,maxx;
long long ans=0;
int st[N];
void dfs(int s,int u)
{
    for(int i=0;i<adj[u].size();i++)
    {
        int v=adj[u][i];
        // cout<<s<<" "<<v<<endl;
        if(!st[v])
        {
            int t1=minn,t2=maxx;
            minn=min(minn,v);
            maxx=max(maxx,v);
            if(min(s,v)-k1<=minn&&maxx<=max(s,v)+k2) ans++;
            st[v]=1;
            dfs(s,v);
            st[v]=0;
            minn=t1,maxx=t2;

        }
    }
}
int main()
{
    cin>>n>>k1>>k2;
    int a[N],b;

    if(n>5000)
    {
        int ma=0,mid;
        for(int i=1;i<n;i++)
        {
            int x,y;
            cin>>x>>y;
            st[x]++;
            st[y]++;
            if(st[x]>ma)
            {
                ma=st[x];mid=x;
            }
            if(st[y]>ma)
            {
                ma=st[y];mid=y;
            }
            if(x==1||y==1)
                if(a[1]) b=max(x,y);
                else a[1]=max(x,y);
            else  a[min(x,y)]=max(x,y);
        }
        if(ma==n-1)
        {
            k2=min(mid-1,k2);
            k1=min(n-mid,k1);
            if(mid>=2&&mid<n)
            {
                ans+=(long long)k2*(mid-2);
                ans-=(long long)k2*(k2-1)/2;
                ans+=(long long)k1*(n-mid-1);
                ans-=(long long)k1*(k1-1)/2;
            }
            else if(mid==1)
            {

                ans+=(long long)k1*(n-mid-1);
                ans-=(long long)k1*(k1-1)/2;
            }
            else
            {
                ans+=(long long)k2*(mid-2);
                ans-=(long long)k2*(k2-1)/2;
            }
            ans+=(long long)(mid-1)*(n-mid);
            ans+=n;
            ans+=n-1;
            cout<<ans;
            return 0;

        }
        int num1=0,ans1=0;
        for(int i=a[1];i;i=a[i])
        {
            num1++;
            if(i-k1<=1)  ans1=num1;
        }
        int num2=0,ans2=0;
        for(int i=b;i;i=a[i])
        {
            num2++;
            if(i-k1<=1)  ans2=num2;
        }

        ans+=(long long)(ans1+num2+1)*(ans1+num2+2);
        ans+=(long long)(ans2+num1+1)*(ans2+num1+2);
        ans-=(long long)(ans2+ans1+1)*(ans2+ans1+2);
        ans=ans/2;
        cout<<ans;
        return 0;
    }
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    for(int i=1;i<=n;i++)
    {
        minn=i;
        maxx=i;
        st[i]=1;
        dfs(i,i);
        st[i]=0;
    }
    cout<<ans/2+n;
    return 0;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值