BOJ-18808シールを貼り付ける


に近づく

  • グラフィックを回転させるルールとマッピング格納方法を設計し、実装すれば、問題を解決することができる.
  • の2つの構造体が使用され、1つは座標を格納するための構造体であり、1つはマップ情報を含む構造体である.
  • struct pos{
        int y,x; //점의 좌표
    };
    struct sticker{
        int y,x; //스티커의 세로,가로 길이
        vector<pos>v; //y by x 형태의 행렬에서 스티커가 내용이 있는 부분의 좌표
    };
  • sticker構造体では、マップのカラー部分が座標で記憶され、90度回転する部分の実現が容易になる.

  • 90度回転のルールは以下の通りです.多くの問題を解決したが、よく覚えていないようだ.
    y座標:現在x座標値
    x座標:回転時のマップの横長-現在のy座標値

  • 以下をコードで表す.
  • swap(cur.v[i].y,cur.v[i].x);
    cur.v[i].x = cur.x-cur.v[i].x-1;

    コード(C+)

    #include <iostream>
    #include <vector>
    #define FIO  ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
    using namespace std;
    int n,m,k,p,arr[41][41],ans;
    struct pos{
        int y,x;
    };
    struct sticker{
        int y,x;
        vector<pos>v;
    };
    vector<sticker>stickers;
    int main(){
        FIO;
        cin>>n>>m>>k;
        for(int i=0;i<k;i++){
            sticker tmp;
            cin>>tmp.y>>tmp.x;
            for(int i=0;i<tmp.y;i++){
                for(int j=0;j<tmp.x;j++){
                    cin>>p;
                    if(p) tmp.v.push_back({i,j});
                }
            }
            tmp.cnt=0;
            stickers.push_back(tmp);
        }
        
        for(auto cur: stickers){
            bool flag = false;
            //위치 탐색
            for(int d=0;d<4;d++){
                //회전
                if(d){
                    swap(cur.y,cur.x);
                    for(int i=0;i<cur.v.size();i++){
                        swap(cur.v[i].y,cur.v[i].x);
                        cur.v[i].x = cur.x-cur.v[i].x-1;
                    }
                }
    
                for(int i=0;i<n-(cur.y-1);i++){
                    for(int j=0;j<m-(cur.x-1);j++){
                        //스티커 붙일 수 있는지 확인
                        flag = true;
                        for(auto it:cur.v){
                            if(arr[i+it.y][j+it.x]){
                                flag = false;
                                break;
                            }
                        }
                        //붙일수있다면 붙이고 넘어감
                        if(flag){
                            for(auto it:cur.v) arr[i+it.y][j+it.x]=1;
                            break;
                        }
                    }
                    if(flag) break;
                }
                //붙였다면 건너뛰기
                if(flag) break;
            }
        }
        
        //남은공간 카운트
        for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(arr[i][j]) ans+=1;
        cout<<ans<<"\n";
        return 0;
    }
    

    結果