Colored Cubes UVA - 1352

问题

分析

这题的重点在于如何表示正方体的姿态,正方体的姿态可以有顶面和正面两个面唯一确定,关键是打表
按照书上的表示方法,1:正面,2右面,3顶面,4底面,5左面,6背面,可以用程序写出24种全部的姿态
标准姿态:{1 2 3 4 5 6}
向前翻:{3,2,6,1,5,4} 顶面变成正面,后面变成顶面
向左转:{5,1,3,4,6,2} 正面变成右面,顶面不变
比较最少多少个面使得正方体相同,所以先是枚举所有的组合,24^3(第一个正方体作为基准)种,然后再计算每种组合需要多少次涂色才能相同

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn=15;
int up[6]={2,1,5,0,4,3},Left[6]={4,0,2,3,5,1};

void rotate(int T[6],int p[6]){
    int temp[6];
    memcpy(temp,p,sizeof(temp));
    for(int i=0;i<6;++i){
        p[i]=temp[T[i]];
    }
}

void emurate_permutation(){
    int p0[6]={0,1,2,3,4,5};  //标准姿态
    printf("int dice={\n");
    for(int i=0;i<6;++i){
        int p[6];
        memcpy(p,p0,sizeof(p0));
        if(i==0) {rotate(up,p); rotate(up,p); rotate(up,p);}
        if(i==1) {rotate(Left,p); rotate(up,p);}
        if(i==3) {rotate(up,p); rotate(up,p);}
        if(i==4) { rotate(Left,p); rotate(up,p); rotate(up,p); rotate(up,p);}
        if(i==5) rotate(up,p);
        for(int j=0;j<4;++j){
            printf("{%d,%d,%d,%d,%d,%d},\n",p[0],p[1],p[2],p[3],p[4],p[5]);
            rotate(Left,p);
        }
    }
    printf("};\n");
}

int main(void){
    emurate_permutation();
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
using namespace std;
const int maxn=4;
int dice24[24][6]={
        {3,1,0,5,4,2},
        {4,3,0,5,2,1},
        {2,4,0,5,1,3},
        {1,2,0,5,3,4},
        {2,0,1,4,5,3},
        {5,2,1,4,3,0},
        {3,5,1,4,0,2},
        {0,3,1,4,2,5},
        {0,1,2,3,4,5},
        {4,0,2,3,5,1},
        {5,4,2,3,1,0},
        {1,5,2,3,0,4},
        {5,1,3,2,4,0},
        {4,5,3,2,0,1},
        {0,4,3,2,1,5},
        {1,0,3,2,5,4},
        {3,0,4,1,5,2},
        {5,3,4,1,2,0},
        {2,5,4,1,0,3},
        {0,2,4,1,3,5},
        {2,1,5,0,4,3},
        {4,2,5,0,3,1},
        {3,4,5,0,1,2},
        {1,3,5,0,2,4},
};
int dice[maxn][6],n,color[maxn][6],d[maxn],ans;
map<string,int> str2id;
vector<string> id2str;
string s;
int ID(string &s){
    if(str2id.count(s)) return str2id[s];
    id2str.push_back(s);
    return str2id[s]=id2str.size()-1;
}

int cal(){
    for(int i=0;i<n;++i){
        for(int j=0;j<6;++j){
            color[i][j]=dice[i][dice24[d[i]][j]];
        }
    }
    int tot=0,cnt[maxn*6];
    for(int j=0;j<6;++j){
        memset(cnt,0,sizeof(cnt));
        int maxv=0;
        for(int i=0;i<n;++i){
            maxv=max(maxv,++cnt[color[i][j]]);
        }
        tot+=n-maxv;
    }
    ans=min(ans,tot);
    return ans;
}

void dfs(int dep){
    if(dep==n){
        cal();
        return;
    }
    for(int i=0;i<24;++i){
        d[dep]=i;
        dfs(dep+1);
    }
}

int main(void){
    while(scanf("%d",&n)==1 && n){
        str2id.clear();
        id2str.clear();
        for(int i=0;i<n;++i){
            for(int j=0;j<6;++j){
                cin>>s;
                dice[i][j]=ID(s);
            }
        }
        ans=6*n;
        d[0]=0;  //0号正方体可以保持一个姿态不动
        dfs(1);
        printf("%d\n",ans);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值