2023 Hubei Provincial Collegiate Programming Contest Finished

2023 Hubei Provincial Collegiate Programming Contest

C - Darkness I

思路:对于n,m相同的情况,最小的是取对角线上的格子,为min(n,m);对于n,m不相同的情况,最小的是先取可形成的最大的正方形,为min(n,m),对于剩余的abs(n-m)行/列,最小的情况是每隔一行/列取一个,并且最右边一定取一个,判断下奇偶即可

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7;

const double eps=1e-6;
typedef long long ll;

int n,m;
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    int res;
    if(n==1||m==1){
        int s=max(n,m);
        res=s/2+1;
    }else{
        res=min(n,m);
        int s=max(m,n)-min(n,m);
        res+=s/2;
        if(s%2)res++;
    }
    cout<<res;
    return 0;
}
View Code

 

F - Inverse Manacher

思路:由于只含字符a和b,固定第一个字符,判断每个 “|”的半径,若为1,则下一个字符与前一个字符不同,否则相同 

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;

typedef pair<string,int>PSI;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7;

const double eps=1e-6;
typedef long long ll;

int n;
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
    string s="a";
    for(int i=1,x;i<=2*n+2;++i){
        cin>>x;
        if(i>=4&&i%2==0&&i<2*n+2){
            char c=s[s.size()-1],y;
            if(x==1){
                if(c=='a')y='b';
                else y='a';
            }
            else {
                if(c=='a')y='a';
                else y='b';
            }
            s+=y;
        }
    }
    cout<<s;
    return 0;
}
View Code

 

H - Binary Craziness

思路:入度范围为2m,入度种数范围为√ 2m,统计所有种数个数,暴力枚举每两种入度的 f 乘上 个数积 

#include<bits/stdc++.h>
using namespace std;
#define int long long
int du[1000006];
int g[2000006];
const int mod=998244353;
signed main(){
    ios::sync_with_stdio(false),cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    for (int i = 0; i <m ; ++i) {
        int x,y;
        cin>>x>>y;
        du[x]++,du[y]++;
    }
    for (int i = 1; i <=n ; ++i) {
        g[du[i]]++;
    }
    vector<pair<int,int>>f;
    for (int i =1; i <=2*m ; ++i) {
        if(g[i]>0){
            f.push_back({i,g[i]});
        }
    }

    int res=0;
    for (int i = 0; i <f.size() ; ++i) {
        for (int j = i+1; j <f.size() ; ++j) {
            res=(res+(f[i].second*f[j].second%mod*(f[i].first^f[j].first)*(f[i].first&f[j].first)*(f[i].first|f[j].first)))%mod;
        }
    }
    cout<<res<<endl;
}
View Code

 

J - Expansion

思路:每一秒加的是所有开垦过的系数和,若满足开垦该块地后下一秒末的能源大于等于0则可开垦该块地;统计系数前缀和b[i],前缀最大值ma[i](第一个最大值);遍历b,当 b[i]+当前能源 小于0时,说明当前不满足开垦第i块地的情况,那就要在b[1~i-1]max中多停留 秒,增加的能源add为 t*b[1~i-1]max,使得b[i]+当前能源+add大于等于0,且b[1~i-1]max一定要大于0;最后最小时间即为所有多停留的时间加上n;

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;

typedef pair<string,int>PSI;
const int N=1e5+5,INF=0x3f3f3f3f,Mod=1e9+7;

const double eps=1e-6;
typedef long long ll;
typedef pair<ll,ll>PLL;
int n;
ll a[N],b[N];
ll ma[N];
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;

    for(int i=1;i<=n;++i){
        cin>>a[i],b[i]=b[i-1]+a[i];
        ma[i]=max(b[i],ma[i-1]);

    }
    if(b[n]<0||b[1]<0)cout<<"-1";
    else{
        ll res=0,all=0,add=0;
        for(int i=1;i<=n;++i){
            if(b[i]<0){

                if(b[i]+all+add>=0){
                    all+=b[i];
                    continue;
                }
                ll s=-b[i],ss=ma[i];
                s-=(all+add);
                if(ss<=0){
                    cout<<"-1";
                    return 0;
                }
                ll t=ceil(1.0*s/ss);
                res+=t;
                add+=t*ss;
            }
            all+=b[i];
        }
        res+=n;
        cout<<res;
    }
    return 0;
}
View Code

 

K - Dice Game

思路:剩下的人的概率都相同,当为xi时,对于一个人来说,第一次赢他的概率为(m-x)/m,第j次赢他的概率为(m-x)/mj,总概率为

(m-x)*(1/m+1/m2+...+1/mj)=(m-x)(1-1/mj)/(m-1)=(m-x)/(m-1)

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=998244353;

const double eps=1e-6;
typedef long long ll;

ll n,m;
ll ksm(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%Mod;
        a=a*a%Mod;
        b>>=1;
    }
    return res%Mod;
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;++i){
        ll res=ksm((m-i)*ksm(m-1,Mod-2)%Mod,n);
        cout<<res<<' ';
    }
    return 0;
}
View Code

 

M - Different Billing

 思路:暴力举出b,满足y=1000b+2500c且b+c小于等于x

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=998244353;

const double eps=1e-6;
typedef long long ll;

int x,y;

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>x>>y;
    for(int i=0;i<=x;++i){
        if((y-1000*i)%2500==0){
            int c=(y-1000*i)/2500;
            if(c<=x-i){
                cout<<x-i-c<<' '<<i<<' '<<c;return 0;
            }
        }
    }
    cout<<-1;
    return 0;
}
View Code

 

posted @ 2023-05-09 23:32  bible_w  阅读(87)  评论(0编辑  收藏  举报