提出 #73454991


ソースコード 拡げる

#include <bits/stdc++.h>
using namespace std;

static const int DX[4] = {1,-1,0,0};
static const int DY[4] = {0,0,1,-1};

int N,M,T,U;
vector<vector<int>> V;
vector<pair<int,int>> start_pos;

struct State {
    vector<pair<int,int>> pos;
    vector<vector<int>> owner;
    vector<vector<int>> level;
};

bool in_bounds(int x,int y){
    return x>=0 && x<N && y>=0 && y<N;
}

// BFS で到達可能領土取得
vector<pair<int,int>> get_reachable(int pid, const State& st){
    vector<pair<int,int>> res;
    queue<pair<int,int>> q;
    vector<vector<int>> vis(N, vector<int>(N,0));

    auto [sx,sy]=st.pos[pid];
    q.push({sx,sy});
    vis[sx][sy]=1;

    while(!q.empty()){
        auto [x,y]=q.front(); q.pop();
        if(st.owner[x][y]!=pid) continue;
        res.push_back({x,y});
        for(int d=0;d<4;d++){
            int nx=x+DX[d], ny=y+DY[d];
            if(in_bounds(nx,ny)&&!vis[nx][ny]){
                vis[nx][ny]=1;
                q.push({nx,ny});
            }
        }
    }
    return res;
}

// 合法手集合
vector<pair<int,int>> get_candidates(int pid,const State& st){
    auto reach=get_reachable(pid,st);
    set<pair<int,int>> cand;
    for(auto [x,y]:reach){
        cand.insert({x,y});
        for(int d=0;d<4;d++){
            int nx=x+DX[d], ny=y+DY[d];
            if(in_bounds(nx,ny))
                cand.insert({nx,ny});
        }
    }
    // 他プレイヤー駒除外
    for(int i=0;i<M;i++){
        if(i==pid) continue;
        cand.erase(st.pos[i]);
    }
    return vector<pair<int,int>>(cand.begin(), cand.end());
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin>>N>>M>>T>>U;
    V.assign(N,vector<int>(N));
    for(int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            cin>>V[i][j];

    start_pos.resize(M);
    for(int i=0;i<M;i++)
        cin>>start_pos[i].first>>start_pos[i].second;

    State st;
    st.pos=start_pos;
    st.owner.assign(N,vector<int>(N,-1));
    st.level.assign(N,vector<int>(N,0));
    for(int i=0;i<M;i++){
        auto [x,y]=start_pos[i];
        st.owner[x][y]=i;
        st.level[x][y]=1;
    }

    for(int turn=0;turn<T;turn++){

        // 自分の候補
        auto cand0=get_candidates(0,st);

        // AIごとの確率分布
        vector<vector<double>> P(M, vector<double>(N*N,0.0));

        for(int pid=1;pid<M;pid++){
            auto cand=get_candidates(pid,st);
            if(cand.empty()) continue;

            int K=cand.size();
            vector<double> score(K);

            for(int i=0;i<K;i++){
                auto [x,y]=cand[i];
                int owner=st.owner[x][y];
                int lv=st.level[x][y];
                double val=V[x][y];
                if(owner==-1) score[i]=val;
                else if(owner==pid){
                    if(lv<U) score[i]=val;
                    else score[i]=0;
                }
                else{
                    if(lv==1) score[i]=val;
                    else score[i]=val*0.5;
                }
            }

            double mx=*max_element(score.begin(),score.end());
            int cnt=0;
            for(double s:score)
                if(abs(s-mx)<1e-9) cnt++;

            double eps=0.3; // 固定近似
            for(int i=0;i<K;i++){
                double prob=eps*(1.0/K);
                if(abs(score[i]-mx)<1e-9)
                    prob+=(1.0-eps)*(1.0/cnt);
                int idx=cand[i].first*N + cand[i].second;
                P[pid][idx]=prob;
            }
        }

        // 手評価
        double best_score=-1e18;
        pair<int,int> best_move=cand0[0];

        for(auto [x,y]:cand0){

            double survive=1.0;
            int idx=x*N+y;
            for(int pid=1;pid<M;pid++)
                survive*= (1.0 - P[pid][idx]);

            int owner=st.owner[x][y];
            int lv=st.level[x][y];

            double gain=0;
            if(owner==-1) gain=V[x][y];
            else if(owner==0){
                if(lv<U) gain=V[x][y];
            }
            else{
                if(lv==1) gain=2*V[x][y];
                else gain=-V[x][y];
            }

            if(turn>60) gain*=1.5;

            double eval=survive*gain;

            if(eval>best_score){
                best_score=eval;
                best_move={x,y};
            }
        }

        cout<<best_move.first<<" "<<best_move.second<<endl;
        cout.flush();

        // 盤面更新読み込み
        vector<pair<int,int>> tx(M), ex(M);
        for(int i=0;i<M;i++)
            cin>>tx[i].first>>tx[i].second;
        for(int i=0;i<M;i++)
            cin>>ex[i].first>>ex[i].second;
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
                cin>>st.owner[i][j];
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
                cin>>st.level[i][j];

        st.pos=ex;
    }
}

提出情報

提出日時
問題 A - Multi-Player Territory Game
ユーザ kuruma_zensoku
言語 C++23 (GCC 15.2.0)
得点 10256565
コード長 5033 Byte
結果 AC
実行時間 11 ms
メモリ 3772 KiB

ジャッジ結果

セット名 test_ALL
得点 / 配点 10256565 / 100000000000
結果
AC × 100
セット名 テストケース
test_ALL test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt
ケース名 結果 実行時間 メモリ
test_0000.txt AC 9 ms 3636 KiB
test_0001.txt AC 11 ms 3712 KiB
test_0002.txt AC 9 ms 3764 KiB
test_0003.txt AC 9 ms 3772 KiB
test_0004.txt AC 11 ms 3764 KiB
test_0005.txt AC 8 ms 3712 KiB
test_0006.txt AC 9 ms 3764 KiB
test_0007.txt AC 6 ms 3696 KiB
test_0008.txt AC 10 ms 3584 KiB
test_0009.txt AC 9 ms 3712 KiB
test_0010.txt AC 8 ms 3732 KiB
test_0011.txt AC 8 ms 3612 KiB
test_0012.txt AC 7 ms 3688 KiB
test_0013.txt AC 10 ms 3712 KiB
test_0014.txt AC 7 ms 3636 KiB
test_0015.txt AC 9 ms 3700 KiB
test_0016.txt AC 6 ms 3700 KiB
test_0017.txt AC 6 ms 3576 KiB
test_0018.txt AC 11 ms 3732 KiB
test_0019.txt AC 8 ms 3712 KiB
test_0020.txt AC 8 ms 3612 KiB
test_0021.txt AC 6 ms 3636 KiB
test_0022.txt AC 11 ms 3688 KiB
test_0023.txt AC 9 ms 3712 KiB
test_0024.txt AC 9 ms 3636 KiB
test_0025.txt AC 9 ms 3644 KiB
test_0026.txt AC 10 ms 3732 KiB
test_0027.txt AC 9 ms 3688 KiB
test_0028.txt AC 6 ms 3560 KiB
test_0029.txt AC 8 ms 3712 KiB
test_0030.txt AC 11 ms 3700 KiB
test_0031.txt AC 8 ms 3744 KiB
test_0032.txt AC 10 ms 3612 KiB
test_0033.txt AC 6 ms 3560 KiB
test_0034.txt AC 8 ms 3612 KiB
test_0035.txt AC 10 ms 3696 KiB
test_0036.txt AC 9 ms 3700 KiB
test_0037.txt AC 10 ms 3696 KiB
test_0038.txt AC 9 ms 3764 KiB
test_0039.txt AC 10 ms 3704 KiB
test_0040.txt AC 8 ms 3584 KiB
test_0041.txt AC 7 ms 3772 KiB
test_0042.txt AC 9 ms 3584 KiB
test_0043.txt AC 9 ms 3764 KiB
test_0044.txt AC 8 ms 3612 KiB
test_0045.txt AC 7 ms 3576 KiB
test_0046.txt AC 7 ms 3584 KiB
test_0047.txt AC 6 ms 3560 KiB
test_0048.txt AC 7 ms 3588 KiB
test_0049.txt AC 9 ms 3732 KiB
test_0050.txt AC 8 ms 3696 KiB
test_0051.txt AC 7 ms 3732 KiB
test_0052.txt AC 6 ms 3628 KiB
test_0053.txt AC 8 ms 3664 KiB
test_0054.txt AC 8 ms 3744 KiB
test_0055.txt AC 10 ms 3772 KiB
test_0056.txt AC 8 ms 3560 KiB
test_0057.txt AC 7 ms 3712 KiB
test_0058.txt AC 9 ms 3624 KiB
test_0059.txt AC 7 ms 3704 KiB
test_0060.txt AC 11 ms 3636 KiB
test_0061.txt AC 8 ms 3712 KiB
test_0062.txt AC 11 ms 3712 KiB
test_0063.txt AC 7 ms 3732 KiB
test_0064.txt AC 8 ms 3696 KiB
test_0065.txt AC 10 ms 3696 KiB
test_0066.txt AC 9 ms 3744 KiB
test_0067.txt AC 8 ms 3680 KiB
test_0068.txt AC 11 ms 3712 KiB
test_0069.txt AC 7 ms 3696 KiB
test_0070.txt AC 11 ms 3772 KiB
test_0071.txt AC 6 ms 3584 KiB
test_0072.txt AC 10 ms 3612 KiB
test_0073.txt AC 10 ms 3616 KiB
test_0074.txt AC 11 ms 3628 KiB
test_0075.txt AC 6 ms 3616 KiB
test_0076.txt AC 8 ms 3636 KiB
test_0077.txt AC 9 ms 3628 KiB
test_0078.txt AC 9 ms 3712 KiB
test_0079.txt AC 9 ms 3712 KiB
test_0080.txt AC 10 ms 3712 KiB
test_0081.txt AC 9 ms 3732 KiB
test_0082.txt AC 7 ms 3696 KiB
test_0083.txt AC 10 ms 3772 KiB
test_0084.txt AC 8 ms 3612 KiB
test_0085.txt AC 9 ms 3732 KiB
test_0086.txt AC 9 ms 3688 KiB
test_0087.txt AC 7 ms 3560 KiB
test_0088.txt AC 9 ms 3764 KiB
test_0089.txt AC 10 ms 3552 KiB
test_0090.txt AC 10 ms 3696 KiB
test_0091.txt AC 9 ms 3688 KiB
test_0092.txt AC 9 ms 3636 KiB
test_0093.txt AC 9 ms 3688 KiB
test_0094.txt AC 7 ms 3704 KiB
test_0095.txt AC 10 ms 3672 KiB
test_0096.txt AC 10 ms 3764 KiB
test_0097.txt AC 11 ms 3664 KiB
test_0098.txt AC 9 ms 3696 KiB
test_0099.txt AC 9 ms 3628 KiB