Submission #1143895


Source Code Expand

#include <bits/stdc++.h>

//#define DEBUG


using namespace std;

using ll = long long;
using pii = pair<char,char>;

const int H = 50;
const int W = 50;
const int K = 8;
const int INF = 1 << 29;

const double TIME_LIMIT = 9; // 実行制限時間
struct TimeWatch{
    clock_t start_,end_;
    void start(){start_=clock();}
    double stop(){return (double)(clock()-start_)/CLOCKS_PER_SEC;}
} tw;


bool is_time_limit(){
    return (tw.stop() >= TIME_LIMIT);
}

int gety(pii p){
    return p.first;
}
int getx(pii p){
    return p.second;
}

ll make_rand(){
    static ll x=123456789;
    static ll y=362436069;
    static ll z=521288629;
    static ll w=88675123;
    ll t;
    t=x^(x<<11);
    x=y;y=z;z=w;
    return w=(w^(w>>19))^(t^(t>>8));
}


const int dy[] = {-1, 0, 0, 1};
const int dx[] = {0, -1, 1, 0};

ll field[51][51];
int occupy[51][51];


vector<pii> neibhor(int cy, int cx, int H, int W){
    vector<pii> res;
    for(int i = 0; i < 4; i++){
        const int ny = cy + dy[i];
        const int nx = cx + dx[i];
        // if(ny>=0&&nx>=0&&ny<H&&nx<W){
        res.push_back(pii(ny,nx));
        // }
    }
    return res;
}


void print_occupy(){
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            printf("%3d ", occupy[i][j]);
        }
        puts("");
    }
}

bool is_settable(vector<pii> &st, int occupy[51][51]){
    
    for(pii p : st){
        int y = gety(p);
        int x = getx(p);
        if(occupy[y][x] != -1) return false;
    }

    return true;
}

set<pii> reg(set<pii> s){
    int minx = INF, miny = INF;
    for(pii p : s){
        const int y = gety(p);
        const int x = getx(p);
        minx = min(minx, x);
        miny = min(miny, y);
    }
    set<pii> res;
    for(auto it = s.begin(); it != s.end(); it++){
        res.insert(pii(it->first - miny, it->second - minx));
    }
    return res;
}

void solve1(){

    
    vector<vector<pii> > mino;
    // 8x8の領域で, mappingを行う
    {
        int sy = 0, sx = 0;
        queue<set<pii> > q;
        set<set<pii> > used;
        set<pii> init = {pii(sy, sx)};
        used.insert(init);
        q.push(init);
        set<set<pii> > result;
        while(q.size()){
            set<pii> s = q.front(); q.pop();
            if(s.size() == K){
                result.insert(s);
                continue;
            }
            for(pii p : s){
                int cy = gety(p);
                int cx = getx(p);
                for(pii np : neibhor(cy, cx, H, W)){
                    if(!s.count(np)){
                        set<pii> ns = s;
                        ns.insert(np);
                        // nsを正規化する
                        ns = reg(ns);
                        if(!used.count(ns)){
                            used.insert(ns);
                            q.push(ns);
                        }
                    }
                }
            }
        }
        // cout << result.size() << endl;
        for(set<pii> sp : result){
            mino.push_back(vector<pii>(sp.begin(), sp.end()));
            // bool a[10][10] = {};
            // for(auto p : sp){
            //     a[(int)p.first][(int)p.second] = true;
            // }
            // if(!a[0][0]){
            //     for(int i = 0; i < 8; i++){
            //         for(int j = 0; j < 8; j++){
            //             if(a[i][j])cout<<'#';
            //             else cout<<".";
            //         }
            //         cout << endl;
            //     }
            //     cout << endl;
            // }
        }
    }

    vector<pair<ll, vector<pii> > > cands;
    // minx, minyをi,jにあわせたときの, 設置座標とコストを計算する
    for(int i = 0; i < (int)mino.size(); i++){
        const auto &ps = mino[i];
        for(int oy = 0; oy < H; oy++){
            for(int ox = 0; ox < W; ox++){
                ll r = 1;
                vector<pii> v;
                for(const pii &p : ps){
                    int y = gety(p) + oy;
                    int x = getx(p) + ox;
                    v.push_back(pii(y,x));
                    if(y >= 0 && x >= 0 && y < H && x < W){
                        r *= field[y][x];
                    }
                    else{
                        r = 0;
                    }
                }
                if(r){
                    cands.push_back(make_pair(r, v));
                }
            }
        }
    }

#ifdef DEBUG
    cout << cands.size() << endl;
#endif

    // biggest order
    sort(cands.begin(), cands.end(), 
         [](const pair<ll, vector<pii> > &p1, const pair<ll, vector<pii> > &p2){
             return p1.first > p2.first;
         });


    memset(occupy, -1, sizeof(occupy));

    vector<bool> used(cands.size(), false);
    // 評価値の高い順番にgreedyに設置する
    for(int idx = 0; idx < (int)cands.size(); idx++){
        // 設置可能か調べる
        if(is_settable(cands[idx].second, occupy)){
            used[idx] = true;
            for(pii p : cands[idx].second){
                occupy[gety(p)][getx(p)] = idx;
            }
        }
    }

    // // 時間いっぱいまで適当に山登りでスコアが上がる場所を探す
    // // tieの場合はswapしたい
    // while(!is_time_limit()){
    //     // usedな要素を一つランダムに選び, 元に戻す

    //     // unusedな要素のうち、設置可能になった要素を探す
    //     // 最もスコアが上がる要素で置き換える
        
    // }
    


// #ifdef DEBUG
//     cout << "total peace : " << peaces.size() << endl;
//     // print_occupy();
// #endif


#ifndef DEBUG
    cout << std::count(used.begin(), used.end(), true) << endl;
    for(int idx = 0; idx < (int)cands.size(); idx++){
        if(used[idx]){
            for(pii p : cands[idx].second){
                cout << gety(p) + 1 << " " << getx(p) + 1 << endl;
            }
        }
    }

#endif

}



int main(){
    
    tw.start(); // 時間計測開始
    {
        int h,w,k;
        cin >> h >> w >> k;
    }
    for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
            char ch;
            cin >> ch;
            field[i][j] = ch - '0';
        }
    }
    solve1();
    

    return 0;
}

Submission Info

Submission Time
Task A - Multiple Pieces
User ishikado
Language C++14 (GCC 5.4.1)
Score 945321
Code Size 6538 Byte
Status AC
Exec Time 2681 ms
Memory 198764 KB

Judge Result

Set Name test_01 test_02 test_03 test_04 test_05 test_06 test_07 test_08 test_09 test_10
Score / Max Score 95601 / 1343058 89750 / 1343058 97201 / 1343058 89897 / 1343058 102011 / 1343058 91112 / 1343058 98472 / 1343058 86887 / 1343058 98767 / 1343058 95623 / 1343058
Status
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
AC × 1
Set Name Test Cases
test_01 subtask_01_01.txt
test_02 subtask_01_02.txt
test_03 subtask_01_03.txt
test_04 subtask_01_04.txt
test_05 subtask_01_05.txt
test_06 subtask_01_06.txt
test_07 subtask_01_07.txt
test_08 subtask_01_08.txt
test_09 subtask_01_09.txt
test_10 subtask_01_10.txt
Case Name Status Exec Time Memory
subtask_01_01.txt AC 2385 ms 197228 KB
subtask_01_02.txt AC 2361 ms 197228 KB
subtask_01_03.txt AC 2562 ms 197228 KB
subtask_01_04.txt AC 2630 ms 198764 KB
subtask_01_05.txt AC 2681 ms 198380 KB
subtask_01_06.txt AC 2484 ms 197996 KB
subtask_01_07.txt AC 2513 ms 197996 KB
subtask_01_08.txt AC 2516 ms 197996 KB
subtask_01_09.txt AC 2444 ms 198152 KB
subtask_01_10.txt AC 2422 ms 198764 KB