제출 #1344394

#제출 시각아이디문제언어결과실행 시간메모리
1344394kokokaiMonochrome Points (JOI20_monochrome)C++20
0 / 100
4 ms504 KiB
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define fi first
#define se second
const int N = 4e5+5;
int n,m;
int compid[N],dpl[N],dpr[N];
int a[N];
vector<int> adj[N],g[N];
vector<vector<int>> grid,under;

int to_id(int i,int j){
    return (i-1)*m+j;
}
vector<int> stk;
int low[N],num[N],deleted[N],timer,sccid=0;
void tarjan(int u){
    stk.push_back(u);
    low[u]=num[u]=++timer;
    for(int v:adj[u]){
        if(deleted[v]) continue;
        if(!num[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }else{
            low[u]=min(low[u],num[v]);
        }
    }
    if(low[u] == num[u]){
        ++sccid;
        while(1){
            int v=stk.back();
            stk.pop_back();
            compid[v]=sccid;
            deleted[v]=1;
            if(u == v) break;
        }
    }
}
int vis[N];
vector<int> topo;
void gettopo(int u){
    vis[u]=1;
    for(int v:g[u]){
        if(!vis[v]){
            gettopo(v);
        }
    }
    topo.push_back(u);
}
vector<pair<int,int>> lines;
signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    if(fopen("text.inp","r")){
        freopen("text.inp","r",stdin);
    }
    cin>>n>>m;
    grid.resize(n+1,vector<int>(m+1));
    under.resize(n+2,vector<int>(m+2));
    for(int i=1;i<=n;i++){
        string s;
        cin>>s;
        for(int j=1;j<=m;j++){
            int c=0;
            if(s[j-1] == '#') c=1;
            grid[i][j]=c;
        }
    }
    for(int i=n;i>=1;i--){
        for(int j=1;j<=m;j++){
            if(grid[i][j]){
                under[i][j]=i;
            }else under[i][j]=under[i+1][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){

            if(grid[i][j]){
                if(under[i+1][j]){
                    adj[to_id(i,j)].push_back(to_id(under[i+1][j],j));
                }
                if(under[i][j-1]){
                    adj[to_id(i,j)].push_back(to_id(under[i][j-1],j-1));
                }
                if(under[i][j+1]){
                    adj[to_id(i,j)].push_back(to_id(under[i][j+1],j+1));
                }
                if(grid[i-1][j]){
                    adj[to_id(i,j)].push_back(to_id(i-1,j));
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(grid[i][j]){
                if(!num[to_id(i,j)]){
                    tarjan(to_id(i,j));
                }
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(grid[i][j]){
                int u=to_id(i,j);
                for(int v:adj[u]){
                    //cerr<<u<<' '<<v<<'\n';
                    if(compid[u] != compid[v]){
                        g[compid[v]].push_back(compid[u]);
                    }
                }
            }
        }
    }
    for(int i=1;i<=sccid;i++){
        if(!vis[i]) gettopo(i);
    }
    for(int i=1;i<=sccid;i++){
        dpl[i]=1e9;
        dpr[i]=0;
    }
    reverse(topo.begin(),topo.end());
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(grid[i][j]){
                int u=to_id(i,j);
                u=compid[u];
                if(g[u].size() == 0){
                    dpl[u]=min(dpl[u],j);
                    dpr[u]=max(dpr[u],j);
                }
            }
        }
    }
    for(int i=topo.size()-1;i>=0;i--){
        int u=topo[i];
        for(int v:g[u]){
            dpl[u]=min(dpl[u],dpl[v]);
            dpr[u]=max(dpr[u],dpr[v]);
        }
    }
    for(int i=1;i<=m;i++) cin>>a[i];
    for(int j=1;j<=m;j++){
        int cnt=0;
        if(a[j] == 0) continue;
        for(int i=n;i>=1;i--){
            cnt += grid[i][j];
            if(cnt == a[j]){
                int u=to_id(i,j);
                u=compid[u];
                lines.push_back({dpl[u],dpr[u]});
                break;
            }
        }
    }
    sort(lines.begin(),lines.end(),[&](pair<int,int> a,pair<int,int> b){
        if(a.se != b.se) return a.se < b.se;
        return a.fi < b.fi;
    });
    int ans=0;
    int curp=0;
    for(int i=0;i<lines.size();i++){
        int l=lines[i].fi,r=lines[i].se;
        if(curp < l){
            ans++;
            curp=r;
        }
    }
    cout<<ans<<'\n';
}

컴파일 시 표준 에러 (stderr) 메시지

monochrome.cpp: In function 'int main()':
monochrome.cpp:56:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   56 |         freopen("text.inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...