2023CCPC山东省赛

2023山东省赛

Dashboard - The 13th Shandong ICPC Provincial Collegiate Programming Contest - Codeforces

I 循环
A 排序
G 排序
D 二分
L ⭐⭐ 简单构造
E ⭐⭐ 数学 枚举
B ⭐⭐ 类拓扑排序
J ⭐⭐ 位运算
M ⭐⭐ 几何
K ⭐⭐⭐ 思维&递推
F ⭐⭐⭐ 线段树优化dp
C ⭐⭐⭐ 类后缀数组
H 娱乐

I - Three Dice (枚举)

#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;

using namespace std;
typedef pair<int, int> PII;

constexpr int N = 100 + 10 , INF = 2e9;

int n,m;
int cnt1,cnt2;

bool check(int x)
{
    if(x==1||x==4) return true;
    return false;
}

void cal(int x)
{
    if(check(x)) cnt1+=x;
    else cnt2+=x;
}

void solve()
{
    cin>>n>>m;

    for(int i=1;i<=6;i++)
    {
        for(int j=1;j<=6;j++)
        {
            for(int k=1;k<=6;k++)
            {
                cnt1=0,cnt2=0;
                cal(i);
                cal(j);
                cal(k);
                // cout<<i<<' '<<j<<' '<<k<<' '<<cnt1<<endl;
                if(cnt1==n&&cnt2==m)
                {
                    cout<<"Yes\n";
                    return;
                }
            }
        }
    }

    cout<<"No\n";

}


signed main()
{
    //freopen("check.in","r",stdin);
    //freopen("check.out","r",stdin);
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);

    solve();

    return 0;
}

A - Orders(模拟)

#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;

using namespace std;
typedef pair<int, int> PII;

constexpr int N = 2e5 + 10 , INF = 2e9;

int n,k;
int num[N],s[N];
pair<int,int> q[N];

void solve()
{
    memset(num,0,sizeof num);
    cin>>n>>k;
    int cnt=1;
    map<int,int> mp;
    map<int,int> id;
    for(int i=1;i<=n;i++)
    {
        cin>>q[i].first>>q[i].second;

    }

    sort(q+1,q+n+1);

    for(int i=1;i<=n;i++)
    {
        int a=q[i].first,b=q[i].second;
        if(mp[a]==0)
        {
            mp[a]=cnt;
            id[cnt]=a;
            cnt++;
        }
        num[mp[a]]+=b;

    }

    bool flag=true;
    int left=0;
    for(int i=1;i<cnt;i++)
    {
        int add=(id[i]-id[i-1])*k;
        // cout<<i<<' '<<left<<' '<<id[i]<<' '<<add<<endl;
        if(left+add<num[i])
        {
            flag=false;
            break;
        }
        else
            left=left+add-num[i];
    }

    if(flag) cout<<"Yes\n";
    else cout<<"No\n";
}


signed main()
{
    //freopen("check.in","r",stdin);
    //freopen("check.out","r",stdin);
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T;
    //T=1;
    cin>>T;
    while(T--)
    {
      solve();
    }



    return 0;
}

G - Matching(贪心)

#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;

using namespace std;
typedef pair<int, int> PII;

constexpr int N = 2e5 + 10 , INF = 2e9;

int n;
int a[N];
map<int,vector<int>> mp;

void solve()
{
    mp.clear();
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        mp[i-a[i]].push_back(a[i]);
    }

    int sum=0;
    for(auto it:mp)
    {
        int len=it.second.size();
        for(int i=len-1;i-1>=0;i-=2)
        {
            int a=it.second[i],b=it.second[i-1];
            if(a+b>0) sum+=a+b;
        }
    }

    cout<<sum<<endl;

}


signed main()
{
    //freopen("check.in","r",stdin);
    //freopen("check.out","r",stdin);
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T;
    //T=1;
    cin>>T;
    while(T--)
    {
      solve();
    }



    return 0;
}

L - Puzzle: Sashigane(模拟)

#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;

using namespace std;
typedef pair<int, int> PII;

constexpr int N = 100 + 10 , INF = 2e9;

int n,x,y;
pair<int,int> c[4];
int sz;

int dx[4]={-1,-1,1,1},dy[4]={-1,1,-1,1};

bool check(int x,int y)
{
    if(x>=1&&x<=n&&y>=1&&y<=n) return true;
    return false;
}

void solve()
{
    cin>>n>>x>>y;

    for(int i=0;i<4;i++)
    {
        c[i].first=x;
        c[i].second=y;
    }
    sz=1;

    vector<vector<int>> ans(n,vector<int>(4));
    int cnt=0;
    while(sz!=n)
    {
        // cout<<"初始:\n";
        // for(int i=0;i<4;i++)
        // {
        //     cout<<c[i].first<<' '<<c[i].second<<endl;
        // }
        for(int i=0;i<4;i++)
        {
            int a=c[i].first+dx[i],b=c[i].second+dy[i];
            if(check(a,b))
            {
                c[i].first=a;
                c[i].second=b;
                // cout<<"a:"<<a<<' '<<c[3-i].first<<endl;
                int min_x=min(a,c[3-i].first);
                int max_x=max(a,c[3-i].first);
                int min_y=min(b,c[3-i].second);
                int max_y=max(b,c[3-i].second);
                // cout<<"四角:\n";
                // cout<<min_x<<' '<<min_y<<' '<<max_x<<' '<<max_y<<endl;

                c[0].first=min_x,c[0].second=min_y;
                c[1].first=min_x,c[1].second=max_y;
                c[2].first=max_x,c[2].second=min_y;
                c[3].first=max_x,c[3].second=max_y;

                sz++;
                ans[cnt][0]=a;
                ans[cnt][1]=b;
                ans[cnt][2]=-dx[i]*sz+dx[i];
                ans[cnt++][3]=-dy[i]*sz+dy[i];
                // cout<<a<<' '<<b<<' '<<-dx[i]*sz<<' '<<-dy[i]*sz<<endl;
                break;
            }
        }

        // cout<<"sz:"<<sz<<endl;
        // for(int i=0;i<4;i++)
        // {
        //     cout<<c[i].first<<' '<<c[i].second<<endl;
        // }
    }

    cout<<"Yes\n";
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++)
    {
        for(int j=0;j<4;j++)
        {
            cout<<ans[i][j]<<" \n"[j==3];
        }
    }

}


signed main()
{
    //freopen("check.in","r",stdin);
    //freopen("check.out","r",stdin);
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);

    solve();

    return 0;
}

D - Fast and Fat (二分+贪心)

思路:

求最慢速度的最大值 考虑二分答案
对于答案x,如何判断是否满足条件
假设所有人中小于速度x的有p人,大于等于速度x的有q人
对于q个人来说 可以背负的最大体重是 自己的体重+自己的速度-速度x
所以要满足x是最小速度 首先p要小于等于q
而且 对于p中的每个人 体重不能超过q中每个人背负的最大体重
让q中背负体重从大到小排序 与p中体重从大到小排序 一一对应 如果有一个不满足说明x不能是最小速度

#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;

using namespace std;
typedef pair<int, int> PII;

constexpr int N = 2e5 + 10 , INF = 2e9;

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

bool check(int x)
{
    vector<int> s1,s2;
    for(int i=1;i<=n;i++)
        if(a[i].first>=x) s1.push_back(a[i].second+a[i].first-x);

    for(int i=1;i<=n;i++)
        if(b[i].first<x) s2.push_back(b[i].second);

    if(s1.size()<s2.size()) return false;

    for(int i=0;i<s2.size();i++)
        if(s1[i]<s2[i]) return false;
    return true;

}

void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int v,w;
        cin>>v>>w;
        a[i]=b[i]={v,w};
    }

    sort(a+1,a+n+1,[](PII &a,PII &b){
        return a.first+a.second>b.first+b.second;
    });

    sort(b+1,b+n+1,[](PII &a,PII &b){
        return a.second>b.second;
    });


    int l=a[1].first,r=a[1].second;
    for(int i=1;i<=n;i++)
    {
        l=min(a[i].first,l);
        r=max(a[i].first,r);
    }
    while(l<r)
    {
        int mid=(l+r+1)>>1;
        if(check(mid)) l=mid;
        else r=mid-1;
    }

    cout<<r<<endl;
}


signed main()
{
    //freopen("check.in","r",stdin);
    //freopen("check.out","r",stdin);
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T;
    //T=1;
    cin>>T;
    while(T--)
    {
      solve();
    }



    return 0;
}

E - Math Problem (数学、枚举)

思路:

应该先进行除法在进行乘法 因为先乘再除数没有改变

进行p次乘法后 n的范围为[kp*n,kp*n+kp-1],长度为kp
只要这个范围里面包括 m 的倍数即可停止乘法操作,至多操作logk(m)次

所以枚举除法操作进行几次然后枚举乘法操作进行几次即可

#include <bits/stdc++.h>
#define bug cout << "***************" << endl
#define look(x) cout << #x << " -> " << x << endl
#define endl '\n'
#define int long long
#define YES cout << "YES" << endl;
#define NO cout << "NO" << endl;

using namespace std;
typedef pair<int, int> PII;

constexpr int N = 1000 + 10 , INF = 2e9;

int n,k,m,a,b;

void solve()
{
    cin>>n>>k>>m>>a>>b;
    if(n%m==0)
    {
        cout<<0<<endl;
        return;
    }
    if(k==1)
    {
        cout<<-1<<endl;
        return;
    }

    int ans=1e18,cost=0;
    while(1)
    {
        int base=n%m,len=1;
        for(int i=0; ;i++)
        {
            int left=(m-base)%m;
            if(left<len)
            {
                ans=min(ans,cost+i*a);
                break;
            }
            base=base*k%m;
            len*=k;
        }

        if(n==0) break;
        n/=k;
        cost+=b;
    }

    cout<<ans<<endl;

}


signed main()
{
    //freopen("check.in","r",stdin);
    //freopen("check.out","r",stdin);
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);

    int T;
    cin>>T;
    while(T--)
    {
        solve();
    }

    return 0;
}
posted @ 2024-04-22 23:16  Danc1ng  阅读(229)  评论(0)    收藏  举报