abc322 d ( 枚举 + 几何 + 状态压缩

#include 
using namespace std;
const int f = (1<<16) - 1;

void rotate(string s[]){
    char t[4][4];
    for(int i = 0 ; i < 4 ; i++){
        for(int j = 0 ; j < 4 ; j++){
            t[j][4-i-1] = s[i][j];
        }
    }
    for(int i = 0 ; i < 4 ; i++){
        s[i] = string(t[i] , t[i] + 4);//char数组转换为字符串
    }
}

bool check(int x){
    if(x > 3 || x < 0) return false;
    else return true;
}

int move(string s[] , int x , int y){

    int st = 0 ;
    for(int i = 0 ; i < 4 ; i++){
        for(int j = 0 ; j < 4 ; j++){
            if(s[i][j] == '#'){
                int xx = i + x;
                int yy = j + y;
                if(check(xx) && check(yy)){
                    st |= 1<<(xx * 4 + yy);
                }else{
                    return -1;
                }
            }
        }
    }
    return st;
}





vector solve(){
    vector ret;
    string s[4];
    for(int i = 0 ; i < 4 ; i++) cin>>s[i];
    for(int i = 0 ; i < 4 ; i++) {
        for (int x = -3; x <= 3; x++) {
            for (int y = -3; y <= 3; y++) {
                int v = move(s , x , y );
                if(v >= 0) ret.push_back(v);
            }

        }
        rotate(s);
    }

    return ret;
}



int main() {
    vector r[3];
    for (int i = 0; i < 3; i++) {
        r[i] = solve();
    }
    for (auto x: r[0]) {
        for (auto y: r[1]){
            for (auto z: r[2]) {
                if(((x ^ y) ^ z) == f ){
                    cout<<"Yes";
                    return 0;
                }
            }
        }
    }
    cout<<"No";
    return 0;
}

属于是长知识了,关于枚举这个图形的摆放

首先你得知道这个图形旋转的公式,

然后枚举这个图形所有的移动情况,最多向左右上下移动3个,

处理平移后的图形,将这个图形用二进制压缩一下,16个格子压缩成16位

最后枚举三个图形的所有二进制情况  x ^ y  ^ z ==  f  

你可能感兴趣的:(基本算法,算法,c++,数据结构)