E. Light Up the Grid 题解

[ E. Light Up the Grid ] ( Problem - E - Codeforces )

题解待补……

总之是把2*2网格看成二进制码,每种操作相当于异或操作,预处理16个操作的代价,把每种状态连边,然后跑反向边最短路。

剩下的之后再补~(想不起来就不补了 😛

代码

#include <bits/stdc++.h>
using namespace std;
//-------------------------------------------------------------------------------------------
#define int long long 
#define lost_R ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define P pair<int,int>
#define lowbit(x) (x&(-x))
#define dbg1(x) cout<<"# "<<x<<endl
#define dbg2(x,y) cout<<"# "<<x<<" "<<y<<endl
#define endl '\n'
const int mod=998244353;
const int N=1<<16;
const int INF=0x3f3f3f3f3f3f3f3f;
const int inf=0x3f3f3f3f;
using ar3=array<int,3>;
using ar2=array<int,2>;
//--------------------------------------------------------------------------------------
int a0,a1,a2,a3;
int m;
vector<P> g[N];
int op[16];
struct info{
    int dis,id;
    bool operator < (const info &t) const {
        return  t.dis<dis;
    }
};
priority_queue<info> q;
int dist[N],vis[N];
void dij(int s){
    fill(dist,dist+N,inf);
    dist[s]=0;
    q.push({0,s});
    while(!q.empty()){
        auto [d,x]=q.top();
        q.pop();
        if(vis[x]) continue;
        vis[x]=1;
        for(auto [y,dis]:g[x]){
            if(dist[y]>dist[x]+dis){
                dist[y]=dist[x]+dis;
                q.push({dist[y],y});
            }
        }
    }
}
void init(){
    op[0]=min({8*a0,4*a1,4*a2,2*a3});
    op[1]=op[2]=op[4]=op[8]=a0;
    op[3]=op[12]=min(2*a0,a1);
    op[5]=op[10]=min(2*a0,a2);
    op[6]=op[9]=min(2*a0,a1+a2);
    op[7]=op[11]=op[13]=op[14]=min({3*a0,a0+a3,a0+a1+a2});
    op[15]=min({4*a0,a3,2*a1,2*a2});
    for(int mask=0;mask<(1<<16);mask++){
        for(int oper=0;oper<16;oper++){
            int next_mask=0,cost=op[oper];
            for(int bit=0;bit<16;bit++){
                if(mask&(1<<bit)){
                    int next_bit=bit^oper;
                    if(next_bit!=15) next_mask|=(1<<next_bit);
                }
            }
            g[next_mask].push_back({mask,cost});
        }
    }
    dij(0);
}
void solve(){
    cin>>m;
    int mask=0;
    for(int i=1;i<=m;i++){
        int x=0;
        string t;
        cin>>t;
        x+=(t[0]-'0')<<3;
        x+=(t[1]-'0')<<2;
        cin>>t;
        x+=(t[0]-'0')<<1;
        x+=(t[1]-'0')<<0;
        mask|=(1<<x);
    
    }
    cout<<dist[mask]<<endl;
}
signed main(){
    lost_R;
    // freopen("jia.in","r",stdin);
    // freopen("jia.out","w",stdout);
    int T=1;
    cin>>T>>a0>>a1>>a2>>a3;
    init();
    for(int i=1;i<=T;i++){
        solve();
    }
    return 0;
}
posted @ 2025-07-30 15:28  RYRYR  阅读(77)  评论(0)    收藏  举报