problem solving

백준 32715: 십자가 찾기

finding wangdo 2025. 1. 27. 19:44

https://www.acmicpc.net/problem/32715

 

 

십자가의 중심이 되는 점을 찾고자 한다.

가로줄을 전부 순회하면서 한 점을 중심으로 좌우로 연속으로 2K+1개 칸이 색칠되어 있는 것들을 찾아 십자가 중심의 후보로 넣는다.

세로줄도 똑같이 순회하면서 후보를 찾는다.

이때 겹치는 것이 십자가의 중심이 된다.

 

특정 점을 중심으로 가로로도 세로로도 2K+1개 칸이 색칠되어 있는 점을 말하는 거다.

 

#include <iostream>

using namespace std;
typedef long long ll;




int main()
{
    ll n,m,k;
    cin>>n>>m>>k;
    int a[3100][3100];//색칠 여부를 배열로 저장
    ll ans=0;
    for(ll i=0;i<n;i++)
    {
        for(ll j=0;j<m;j++)
        {
            cin>>a[i][j];
        }
    }
    ll hubo[3100][3100]={0};//정답 후보를 저장
    
    for(ll i=0;i<n;i++)//각 가로줄 먼저 순회
    {
        ll count=0;//연속해서 색칠된 칸의 개수
        for(ll j=0;j<m;j++)
        {
            if(a[i][j]==1)
            {
                count++;//색칠된 칸을 만날 때마다 1씩 더한다
                if(count>=(2*k+1))//연속 색칠된 칸이 2K+1이 된 경우
                {
                    hubo[i][j-k]=1;//그 중앙에 있는 점은 정답 후보가 된다
                }
            }
            else
            {
                count=0;//색칠 안 된 칸을 만나면 count를 0으로 초기화한다
            }
        }
    }
    for(ll j=0;j<m;j++)//세로줄 순회
    {
        ll count=0;//가로줄과 논리는 똑같다.
        
        for(ll i=0;i<n;i++)
        {
            if(a[i][j]==1)
            {
                count++;
                if(count>=(2*k+1))
                {
                    if(hubo[i-k][j]==1)//세로줄에서 찾은 후보가 가로줄에서도 후보라면?
                    {
                        ans++;//그 칸은 정답에 포함된다
                    }
                    
                }
            }
            else
            {
                count=0;
            }
        }
    }
    cout<<ans;
    return 0;
}

 

모든 칸을 하나하나 다 검사하면 시간복잡도가 아주 커진다. 따라서 이 코드는 누적합의 논리를 이용했다.

'problem solving' 카테고리의 다른 글

백준 33489: 수열의 점수  (0) 2025.02.18
백준 33274: 적당한 휴식은 필수  (0) 2025.01.28
백준 31778: PPC 만들기  (0) 2024.12.08
백준 23032: 서프라이즈~  (0) 2024.11.17
백준 13018: 특이한 수  (1) 2023.03.06