23 暑假友谊赛 No.3

23 暑假友谊赛 No.3

A - 把你砍成两半!

思路:确定a1时,当a2~an都为a1的倍数时,条件一定满足

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int c(int a,int b){
    if(b>a)return 0;
    int res=1;
    for(int i=1,j=a;i<=b;++i,--j){
        res=res*j%mod;
        res=res*ksm(i,mod-2)%mod;
    }
    return res;
}
int Lucas(int a,int b){
    if(a<mod&&b<mod)return c(a,b);
    return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod;
}
void init(){

}

void solve(){
    int ans=0,n,k;cin>>n>>k;
    for(int i=1;i<=n;++i){
        if(n/i>=k)ans=(ans+Lucas(n/i-1,k-1))%mod;
    }
    cout<<ans;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    init();
    //cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

B - 小叶,我们加油!

思路:暴力求每一行选每种方案的最小价值,或对每一行dp

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
vector<int>C;
void init(){
}
void solve(){
    int n,m,x,y;cin>>n>>m>>x>>y;
    int a=0,b=0;
    string s;
    for(int i=0;i<n;++i){
        cin>>s;
        s.insert(0,"*");s.push_back('*');
        for(int j=1;j<=m;++j){
            if(s[j]=='.'){
                if(s[j-1]=='*'&&s[j+1]=='*')a++,s[j]='*';
                else if(s[j+1]=='.'){
                    if(y<=2*x)b++;
                    else a+=2;
                    s[j]=s[j+1]='*';j++;
                }
            }
        }
    }
    cout<<a*x+b*y<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    init();
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

C - 工程学的作用不可小觑!

思路:取两个边界即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};


void solve(){
    PII ve[2],a[2];
    for(int i=0;i<2;++i){
        cin>>ve[i].first>>ve[i].second;a[i]=ve[i];
    }
    sort(ve,ve+2);
    if(ve[0].first==a[0].first&&ve[0].second==a[0].second)
    cout<<ve[0].first<<' '<<ve[1].second<<'\n';
    else cout<<ve[1].second<<' '<<ve[0].first<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

D - 做博士的护卫?好哦。

思路:

由两个等式可以推出c=b+1,a2=2b-1<=2n-1,即a<=√2n-1,且a为奇数;

枚举所有的a,即可知道所有的b、c;二分求出n以内的c的个数即可

 

E - 暴虐的恶人阻断正义的道路,我的主人啊,以复仇与恶意为名,引领弱小的人把。

思路:出现次数最大的数即为答案

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};


void solve(){
    int n;cin>>n;
    vector<int>cnt(105,0);
    int ans=0;
    for(int i=0,x;i<n;++i){
        cin>>x;
        cnt[x]++;
        ans=max(ans,cnt[x]);
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    //cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

 F - 我才不会一个人的时候跟仿生海龙聊天!

思路:f[i][j]表示第i种菜选择j的最小代价,f[i][j]=f[i-1][k]+a[i][j],其中(k,j)可搭配;

用multiset维护f[i-1][j]的最小值,枚举第i种菜的每个j,将不能与j搭配的菜删掉,计算完f[i][j]后将删去的菜加回来

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int c(int a,int b){
    if(b>a)return 0;
    int res=1;
    for(int i=1,j=a;i<=b;++i,--j){
        res=res*j%mod;
        res=res*ksm(i,mod-2)%mod;
    }
    return res;
}
int Lucas(int a,int b){
    if(a<mod&&b<mod)return c(a,b);
    return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod;
}
void init(){

}

void solve(){
    vector<int>n(4);
    for(int i=0;i<4;++i)cin>>n[i];
    vector<vector<int>>a(4);
    for(int i=0;i<4;++i){
        a[i]=vector<int>(n[i]);
        for(int j=0;j<n[i];++j)cin>>a[i][j];
    }
    for(int i=1,m;i<4;++i){
        cin>>m;
        vector<vector<int>>g(n[i]);
        for(int j=0,u,v;j<m;++j){
            cin>>u>>v;u--,v--;g[v].push_back(u);
        }
        multiset<int>cnt;
        for(int j=0;j<n[i-1];++j)cnt.insert(a[i-1][j]);
        for(int j=0;j<n[i];++j){
            for(auto k:g[j])
                cnt.erase(cnt.lower_bound(a[i-1][k]));
            if(cnt.empty())a[i][j]=INF;
            else a[i][j]+=*cnt.begin();
            for(auto k:g[j])
                cnt.insert(a[i-1][k]);
        }
    }
    int ans=*min_element(a[3].begin(),a[3].end());
    if(ans>=INF)ans=-1;
    cout<<ans;
    return;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    init();
    //cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

 

G - 不让他们过去就可以了吗?

思路:求出最小的,若大于最小的都可以为winner

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};


void solve(){
    int n;cin>>n;
    vector<int>ve(n);
    int mi=INF;
    for(int i=0;i<n;++i){
        cin>>ve[i];
        mi=min(mi,ve[i]);
    }
    int ans=0;
    for(int i=0;i<n;++i){
        ans+=ve[i]>mi;
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

 H - 唔...这个我真的能做到

思路:

有两种情况,1.x杯热水,x杯冷水,温度为(h+c)/2

2.x+1杯热水,x杯冷水,温度Tx=((x+1)h+xc)/(2x+1),且Tx'<0(求导),(h+c)/2<Tx<=h

若t<=(h+c)/2,答案即为2

否则可二分出答案,或解Tx=t,得出x=(t-h)/(h+c-2t),取x-1、x、x+1中最接近的即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int c(int a,int b){
    if(b>a)return 0;
    int res=1;
    for(int i=1,j=a;i<=b;++i,--j){
        res=res*j%mod;
        res=res*ksm(i,mod-2)%mod;
    }
    return res;
}
int Lucas(int a,int b){
    if(a<mod&&b<mod)return c(a,b);
    return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod;
}
void init(){

}

void solve(){
    int h,c,t;cin>>h>>c>>t;
    if(2*t<=c+h){
        cout<<2<<'\n';return ;
    }
    auto check=[&](int x){
        double fl=((double)(x+1)*h+x*c)/(2*x+1);
        int k=x+1;
        double fr=((double)(k+1)*h+k*c)/(2*k+1);
        double tt=t;
        return fabs(fl-tt)<=fabs(fr-tt);
    };
    int l=0,r=1e9,x;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))x=mid,r=mid-1;
        else l=mid+1;
    }
    cout<<2*x+1<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    init();
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int c(int a,int b){
    if(b>a)return 0;
    int res=1;
    for(int i=1,j=a;i<=b;++i,--j){
        res=res*j%mod;
        res=res*ksm(i,mod-2)%mod;
    }
    return res;
}
int Lucas(int a,int b){
    if(a<mod&&b<mod)return c(a,b);
    return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod;
}
void init(){

}

void solve(){
    int h,c,t;cin>>h>>c>>t;
    if(2*t<=c+h){
        cout<<2<<'\n';return ;
    }
    int x=(t-h)/(h+c-2*t);
    double mi=LDBL_MAX;
    int ans;
    for(int i=max(0ll,x-1);i<=x+1;++i){
        double v=fabs((double)((i+1)*h+i*c)/(double)(2*i+1)-(double)t);
        if(v<mi)mi=v,ans=2*i+1;
    }
    cout<<ans<<'\n';
    return;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    init();
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

 

I - 你爱我不断提升的力量,对吧!

思路:要求分最大,那么一个人取最大,其他人取平均值即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
void init(){
}
void solve(){
    int n,m,k;cin>>n>>m>>k;
    if(m==0)cout<<"0\n";
    else{
        int ma=min(n/k,m),mi=(m-ma+k-2)/(k-1);//cout<<ma<<' '<<mi<<'\n';
        cout<<ma-mi<<'\n';
    }
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    init();
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

J - 把德克萨斯放到我的小队来!

思路:n为偶数时,不需要跳;

n为奇数时,可以发现每隔n/2会跳跃一次,且从第二秒开始算,即跳(k-1)/(n/2)次,k加上多跳的对n取模即为当前位置

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
void init(){
}
void solve(){
    int n,k,ans;cin>>n>>k;
    if(n%2==0){
        ans=k%n;
        if(ans==0)ans=n;
        cout<<ans<<'\n';return;
    }
    int l=(n+1)/2,s=n/2;
    if(k>=l){
        int d=k-l+1,cnt=(d+s-1)/s;
        ans=(k+cnt)%n;
    }
    else ans=k%n;
    if(ans==0)ans=n;
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    init();
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

K - 让德克萨斯来担任队长!

思路:数的范围为[-30,30],考虑枚举删去的数(区间中最大的数),将序列中大于该数的值修改为INT_MIN后求最大子串和即可,最后减去删去的数即为该情况的答案

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int ksm(int x,int y){
    int res=1;
    while(y){
        if(y&1)res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int c(int a,int b){
    if(b>a)return 0;
    int res=1;
    for(int i=1,j=a;i<=b;++i,--j){
        res=res*j%mod;
        res=res*ksm(i,mod-2)%mod;
    }
    return res;
}
int Lucas(int a,int b){
    if(a<mod&&b<mod)return c(a,b);
    return c(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod;
}
void init(){

}

void solve(){
    int n;cin>>n;
    vector<int>ve(n);
    for(int i=0;i<n;++i)cin>>ve[i];
    int ans=0;
    for(int i=0;i<=30;++i){
        vector<int>a=ve;
        for(auto &j:a)
            if(j>i)j=INT_MIN;
        int s=0;
        for(int j=0,c=0;j<n;++j){
            c+=a[j];
            if(c<0)c=0;
            s=max(s,c);
        }
        ans=max(ans,s-i);
    }
    cout<<ans;
    return;
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    init();
    //cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

 

L - 小叶,掩护我们离开这里!

思路:一共有m=n*(n-1)/2条关系,要让每个人分数一样,即每个人赢k=m/n次,为(n-1)/2次;

当n为奇数时,每个人都赢k次刚好够m条关系,不需要平局;

当n为偶数时,可以发现多的关系为m%n,为n/2,刚好将每个人分数加一,即剩余的关系为平局

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353,M=44750;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
void init(){
}
void solve(){
    int n;cin>>n;
    int k=(n-1)/2;
    vector<vector<int>>ve(n+1,vector<int>(n+1,0));
    for(int i=1;i<=n;++i){
        for(int j=i+1,u=1;u<=k;++u,++j){
            int x=j%n;
            if(x==0)x=n;
            ve[i][x]=1;
        }
    }
    for(int i=1;i<n;++i){
        for(int j=i+1;j<=n;++j){
            if(ve[i][j])cout<<1<<' ';
            else if(ve[j][i])cout<<-1<<' ';
            else cout<<0<<' ';
        }
    }
    cout<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    init();
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

 M - 博士面罩下面是什么样的呢,悄悄看看吧..

思路:用双指针维护下前后缀相等的情况

#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=2e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};


void solve(){
    int n;cin>>n;
    vector<int>ve(n+1),l(n+1),r(n+1);
    for(int i=1;i<=n;++i){
        cin>>ve[i];
        l[i]=l[i-1]+ve[i];
    }
    r[n]=ve[n];
    for(int i=n-1;i>=1;--i)r[i]=r[i+1]+ve[i];
    int ans=0;
    int L=1,R=n;
    while(L<R){
        while(r[R]<l[L]&&R>=1&&R>L)R--;
        if(!R||R<=L)break;
        if(l[L]==r[R])ans=max(ans,L+n-R+1);
        L++;
    }
    cout<<ans<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T=1;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}
View Code

 

posted @ 2023-08-03 14:58  bible_w  阅读(6)  评论(0编辑  收藏  举报