(AtCoder Beginner Contest 312)

(AtCoder Beginner Contest 312)

A - Chord

#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;
const double eps=1e-6;


void solve(){
    string s;cin>>s;
    string a[7]={"ACE","BDF","CEG","DFA","EGB","FAC","GBD"};
    for(int i=0;i<7;++i){
        if(s==a[i]){
            cout<<"Yes";return ;
        }
    }
    cout<<"No";
}
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 - TaK Code

思路:维护黑色的前缀和,枚举每个点,满足左上角和右下角的3、4个宽度的黑色个数都为9则输出

#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;
const double eps=1e-6;

int g[105][105];
void solve(){
    int n,m;cin>>n>>m;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            char c;cin>>c;
            if(c=='#')g[i][j]=1;
            g[i][j]+=(g[i-1][j]+g[i][j-1]-g[i-1][j-1]);
        }
    for(int i=1;i+8<=n;++i)
        for(int j=1;j+8<=m;++j){
            int x1=i+2,y1=j+2,a1,a2,b1,b2;
            a1=g[x1][y1]-g[i-1][y1]-g[x1][j-1]+g[i-1][j-1];
            x1=i+3,y1=j+3;
            a2=g[x1][y1]-g[i-1][y1]-g[x1][j-1]+g[i-1][j-1];
            x1=i+5,y1=j+5;
            int x2=i+8,y2=j+8;
            b1=g[x2][y2]-g[x1-1][y2]-g[x2][y1-1]+g[x1-1][y1-1];
            x1=i+6,y1=j+6;
            b2=g[x2][y2]-g[x1-1][y2]-g[x2][y1-1]+g[x1-1][y1-1];
            //if(i==1&&j==10)cout<<a1<<' '<<a2<<' '<<b1<<' '<<b2<<'\n';
            if(a1==a2&&a2==b1&&b1==b2&&b2==9){
                cout<<i<<' '<<j<<'\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

 

C - Invisible Hand

思路:对a、b排序,二分x,比较a中小于等于x的个数和b中大于等于x的个数,找出最小的x

#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;
const double eps=1e-6;


void solve(){
    int n,m;cin>>n>>m;
    vector<int>a(n),b(m);
    for(int i=0;i<n;++i)cin>>a[i];
    for(int i=0;i<m;++i)cin>>b[i];
    sort(a.begin(),a.end()),sort(b.begin(),b.end());
    int l=1,r=1e9+1,ans;
    auto check=[&](int x){
        int p1= upper_bound(a.begin(),a.end(),x)-a.begin();
        int p2= lower_bound(b.begin(),b.end(),x)-b.begin();
        p2=b.size()-p2;
        return p1>=p2;
    };
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    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

 

D - Count Bracket Sequences

思路:对于 ‘( ’计一分,‘ )’计-1分;

dp[i][j]表示前i个字符的情况,且第i个字符选定后,当前的分值为j的情况数

枚举到i时,最多有i分,再枚举0~i分的情况;

那么当s[i]='('时,dp[i][j]=dp[i-1][j-1]

当s[i]=')'时,dp[i][j]=dp[i-1][j+1]

当s[i]='?'时,s[i]可以是'('和')',则dp[i][j]=dp[i][j+1]+dp[i][j-1]

最后的答案即为dp[n][0]

#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=3e3+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int dp[N][N];
void solve(){
    string s;
    cin>>s;int n=s.size();
    s.insert(0," ");
    dp[0][0]=1;
    for(int i=1;i<=n;++i){
        for(int j=0;j<=i;++j){
            if(s[i]=='('&&j-1>=0)dp[i][j]=dp[i-1][j-1]%mod;
            if(s[i]==')'&&j+1<=n)dp[i][j]=dp[i-1][j+1]%mod;
            if(s[i]=='?'){
                if(j-1>=0)dp[i][j]=(dp[i][j]+dp[i-1][j-1])%mod;
                if(j+1<=n)dp[i][j]=(dp[i][j]+dp[i-1][j+1])%mod;
            }
        }
    }
    cout<<dp[n][0];
}
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

 

 

E - Tangency of Cuboids

思路:坐标数据范围为0~100,且没有立方体重叠,用一个三维数组记录每个立方体,每个单位方块由左上角标记;

若两个立方体共面,可以在平行于xoy、xoz、yoz三个面中的一个面上共面,分别为z、y、x相等时;

那么枚举每个点,若点为立方体的最外层中的点,判断将该点平移到相邻面上后是否为其他立方体最外层中的点,是说明这两个立方体共面,用set存下来;

#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=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;

int g[N][N][N];
void solve(){
    int n;cin>>n;
    for(int i=0,x1,y1,z1,x2,y2,z2;i<n;++i){
        cin>>x1>>y1>>z1>>x2>>y2>>z2;
        for(int j1=x1;j1<x2;++j1)
            for(int j2=y1;j2<y2;++j2)
                for(int j3=z1;j3<z2;++j3)
                    g[j1][j2][j3]=i+1;
    }
    vector<set<int>>ans(n+1);
    auto add=[&](int a,int b){
        ans[a].insert(b);
        ans[b].insert(a);
    };
    for(int i=0;i<100;++i)
        for(int j=0;j<100;++j)
            for(int k=0;k<100;++k){
                if(g[i][j][k]){
                    if(g[i+1][j][k]&&g[i+1][j][k]!=g[i][j][k])add(g[i][j][k],g[i+1][j][k]);
                    if(g[i][j+1][k]&&g[i][j+1][k]!=g[i][j][k])add(g[i][j][k],g[i][j+1][k]);
                    if(g[i][j][k+1]&&g[i][j][k+1]!=g[i][j][k])add(g[i][j][k],g[i][j][k+1]);
                }

            }
    for(int i=1;i<=n;++i)cout<<ans[i].size()<<'\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

 

F - Cans and Openers

 思路:对拉环罐头、普通罐头、开罐器进行选择,要让幸福最大,应该优先选择幸福度大的拉环罐头、普通罐头、开罐数大的开罐器,对他们排序就好;

方法一:枚举选择拉环罐头的个数,二分求出选择普通罐头的最大数量,取所有可能的最大幸福

方法二:贪心的想,枚举选择的拉环罐头个数后,而后优先选择幸福度大的普通罐头,若当前的开罐数不够,则先选择一个开罐数最大的开罐器;可以求出所有选择数下,普通罐头带来的最大幸福度

#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=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;


void solve(){
    int n,m;cin>>n>>m;
    vector<int>a(n+1),b(n+1),c(n+1);
    for(int i=1,t,x;i<=n;++i){
        cin>>t>>x;
        if(t==0)a[i]=x;
        else if(t==1)b[i]=x;
        else c[i]=x;
    }
    sort(a.begin()+1,a.end(),greater<int>());
    for(int i=1;i<=n;++i)a[i]+=a[i-1];
    sort(b.begin()+1,b.end());
    sort(c.begin()+1,c.end());
    vector<int>last(n+1,0);
    int cnt=0;
    for(int i=1;i<=n;++i){
        if(b.size()==1)last[i]=last[i-1];
        else if(cnt==0){
            if(c.size()!=1){
                cnt+=c.back();
                c.pop_back();
            }
            last[i]=last[i-1];
        }else{
            cnt--;
            last[i]=last[i-1]+b.back();
            b.pop_back();
        }
    }
    int ans=0;
    for(int i=0;i<=m;++i)ans=max(ans,a[i]+last[m-i]);
    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;
}
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=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const double eps=1e-6;


void solve(){
    int n,m;cin>>n>>m;
    vector<int>a,b,c;
    a.push_back(0),b.push_back(0),c.push_back(0);
    for(int i=1,t,x;i<=n;++i){
        cin>>t>>x;
        if(t==0)a.push_back(x);
        else if(t==1)b.push_back(x);
        else c.push_back(x);
    }
    sort(a.begin()+1,a.end(),greater<int>());
    sort(b.begin()+1,b.end(),greater<int>());
    sort(c.begin()+1,c.end(),greater<int>());
    for(int i=1;i<a.size();++i)a[i]+=a[i-1];
    for(int i=1;i<b.size();++i)b[i]+=b[i-1];
    for(int i=1;i<c.size();++i)c[i]+=c[i-1];
    int A=a.size()-1,B=b.size()-1,C=c.size()-1;
    int ans=0;
    for(int i=0,l,r,mid,cnt;i<=min(m,A);++i){
        l=0,r=min(m-i,B);
        while(l<=r){
            mid=l+r>>1;
            if(c[min(C,m-i-mid)]>=mid)cnt=mid,l=mid+1;
            else r=mid-1;
        }
        ans=max(ans,a[i]+b[cnt]);
    }
    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;
}
1

 

G - One More Grid Task

思路:求不在一条路径的三个点(i,j,k)的数量;找出在一条路径上的(i,j,k)的数量s,C(n,3)-s即可;

求出以每个点为根的子树的节点数,含该点的路径有两种情况:还有两个点分别在不同的子树、还有两个点分别在子树和非子树上,统计所有的情况即可

#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;

vector<int>ve[N],g[N];
vector<int>cnt(N+1);
void dfs(int u){
    cnt[u]=1;
    for(auto v:ve[u]){
        if(cnt[v])continue;
        g[u].push_back(v);
        dfs(v);
        cnt[u]+=cnt[v];
    }
}
void solve(){
    int n;cin>>n;
    for(int i=1,x,y;i<n;++i){
        cin>>x>>y;
        ve[x].push_back(y),ve[y].push_back(x);
    }
    int ans=n*(n-1)*(n-2)/6;
    dfs(1);
    for(int i=1,c;i<=n;++i){
        c=0;
        for(auto v:g[i])c+=cnt[v]*(cnt[i]-cnt[v]-1);
        c/=2;
        c+=(cnt[i]-1)*(n-cnt[i]);
        ans-=c;
    }
    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

 

posted @ 2023-07-29 22:14  bible_w  阅读(218)  评论(2编辑  收藏  举报