AtCoder Beginner Contest 311

AtCoder Beginner Contest 311

First ABC

思路:找到第一个a,b,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=1e6+5,INF=0x3f3f3f3f,Mod=1e9+7;
const double eps=1e-6;

void solve(){
    int n;cin>>n;
    string s;
    cin>>s;
    int a=0,b=0,c=0;
    for(int i=0;i<n;++i){
        if(s[i]=='A')a=1;
        if(s[i]=='B')b=1;
        if(s[i]=='C')c=1;
        if(a&&b&&c){
            cout<<i+1;
            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

 

Vacation Together

思路:找到最大的连续'o'的列长度

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

void solve(){
    int n,d,ans=0;cin>>n>>d;
    vector<string>ve(n);
    for(int i=0;i<n;++i)cin>>ve[i];
    char pre='o';
    for(int i=0,c=0;i<d;++i){
        bool ok=true;
        for(int j=1;j<n;++j)if(ve[j][i]!=ve[j-1][i]){
            ok=false;break;
        }
        if(ok&&ve[0][i]==pre)c++;
        else c=0;
        ans=max(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

 

Find it!

思路:每个点都指向一点,那么一定有环,从一点开始搜,搜到搜过的点即找到环

#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 n;
vector<int>ve(N);
vector<int>st(N);
int dfs(int u){
    if(st[u]){
        return u;
    }
    st[u]=1;
    return dfs(ve[u]);
}
void solve(){
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>ve[i];
    }
    st[1]=1;
    int res=dfs(ve[1]);
    vector<int>ans;
    int p=ve[res];
    ans.push_back(res);
    while(p!=res){
        ans.push_back(p);
        p=ve[p];
    }
    cout<<ans.size()<<'\n';
    for(auto v:ans)cout<<v<<' ';
}
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

 

Grid Ice Floor

思路:从(1,1)开始bfs,一个方向要搜到底,标记搜过的点,最后统计

#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 n,m,ans=0;
vector<string>s(205);
int st[205][205],vis[205][205];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void bfs(int x,int y){
    queue<PII>q;
    q.push({x,y});
    st[1][1]=vis[1][1]=1;
    while(q.size()){
        auto [u,v]=q.front();q.pop();
        for(int i=0;i<4;++i){
            int xx=u,yy=v;
            while(s[xx+dx[i]][yy+dy[i]]!='#'){
                xx+=dx[i],yy+=dy[i];
                vis[xx][yy]=1;
            }
            if(!st[xx][yy]){
                q.push({xx,yy});
                st[xx][yy]=1;
            }
        }
    }
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)ans+=vis[i][j];
}
void solve(){
    cin>>n>>m;
    for(int i=0;i<n;++i){
        cin>>s[i];
    }
    bfs(1,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

 

 Defect-free Squares

思路:把洞的地方标为1,用前缀和判断是否为正方形。枚举每个点,二分找到以该点为右下角的最大正方形

#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 int inf=0x3f3f3f3f3f3f;
const double eps=1e-6;
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};

int h,w,n;
int a[N][N];
void solve(){
    cin>>h>>w>>n;
    for(int i=0,u,v;i<n;++i){
        cin>>u>>v;
        a[u][v]=1;
    }
    int res=0;

    for(int i=1;i<=h;++i)
        for(int j=1;j<=w;++j){
            if(!a[i][j]){
                a[i][j]+=(a[i-1][j]+a[i][j-1]-a[i-1][j-1]);
                int l=0,r=min(i,j)-1,k;
                while(l<=r){
                    int mid=l+r>>1;
                    auto check=[&](int x){
                        int ii=i-x,jj=j-x;
                        int s=a[i][j]-a[i][jj-1]-a[ii-1][j]+a[ii-1][jj-1];
                        return !s;
                    };
                    if(check(mid))k=mid,l=mid+1;
                    else r=mid-1;
                }
                //cout<<i<<' '<<j<<':'<<k<<'\n';
                res+=(k+1);
            }
            else a[i][j]+=(a[i-1][j]+a[i][j-1]-a[i-1][j-1]);
        }
    cout<<res;

}
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 - Yet Another Grid Task

思路:dp[i][j]表示前i列,第j行以及以下的行都为黑的数量。

dp[i][j]状态转移: 1. s[i][j]自己变为黑:dp[i][j] = dp[i-1][j~m]

        2.s[i][j]受s[i-1][j-1]的影响而变黑 dp[i][j] = dp[i-1][j-1]

        即dp[i][j] = dp[i-1][ (j-1)~ m],可直接维护前一列的行的后缀和;

这里dp[0][n+1] = 1;

dp[i][j]只和前一列有关系,可优化为一维

#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 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,m;cin>>n>>m;
    vector<string>s(n);
    for(int i=0;i<n;++i)cin>>s[i];
    for(int i=0;i<n;++i){
        for(int j=0;j<m;++j){
            if(s[i][j]=='#'&&i+1<n){
                s[i+1][j]='#';
                if(j+1<m)s[i+1][j+1]='#';
            }
        }
    }
    vector<int>dp(n+1,0);
    dp[n]=1;
    for(int i=0;i<m;++i){
        vector<int>f(n+1,0);
        int pre=0;
        for(int j=n;j>=0;--j){
            pre=(pre+dp[j])%mod;
            if(j&&s[j-1][i]=='#')continue;
            f[j]=pre;
            if(j)f[j]=(f[j]+dp[j-1])%mod;
        }
        dp=f;
    }
    int ans=0;
    for(int i=0;i<=n;++i)ans=(ans+dp[i])%mod;
    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

 

posted @ 2023-07-25 14:43  bible_w  阅读(66)  评论(0编辑  收藏  举报