uvaLive 3401 Colored Cubes 暴力





题意:给出n个立方体,(n<=4),每个面上均有颜色,问最少重新涂多少个面的颜色使得所有立方体相同。

解法:暴力枚举,难在编写程序。

一个立方体有24个姿势,因为上面有6中可能,难后前面又有4中可能,故有24种可能。

现在让第一个立方体任选一种姿势,然后枚举其他立方体的姿势,然后在姿势不变的情况下涂色,求最少涂色数。


对于每一个面,找出n个立方体中最多的颜色color,它的数量为cnt[color],然后所有立方体的这个面共需要重涂n-cnt[color] 次。


0 正面

1 右

2 上

3 下

4 左

5 反面


主代码:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxn=4    ;

map<string ,int >mp;
char s[30];
int cube24[24][6]={
{2,1,5,0,4,3},{2,0,1,4,5,3},{2,4,0,5,1,3},{2,5,4,1,0,3},
//第一行表示,编号为0的面现在都在原来编号为2的面的位置。
{4,2,5,0,3,1},{5,2,1,4,3,0},{1,2,0,5,3,4},{0,2,4,1,3,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},{1,0,3,2,5,4},{0,4,3,2,1,5},{4,5,3,2,0,1},
{1,3,5,0,2,4},{0,3,1,4,2,5},{4,3,0,5,2,1},{5,3,4,1,2,0},
{3,1,0,5,4,2},{3,0,4,1,5,2},{3,4,5,0,1,2},{3,5,1,4,0,2}
};

int n,ans,N,r[maxn+3],color[maxn+3][maxn+3],cube[maxn+3][maxn+3];

int ID(char* s)
{
    string ss(s);
    if(mp.count(s))
    {
       return mp[s];
    }
    mp[s]=N++;
    return mp[s];
}


int cnt[4*24+5];
void check()
{
    for0(i,n)
    {
        for0(j,6)
        {
           color[i][cube24[r[i]][j]] =cube[i][j] ;
        }

    }


    int tot=0;
    for(int j=0;j<6;j++)//枚举面
    {
        int maxi=0;
        memset(cnt,0,sizeof cnt);
        for(int i=0;i<n;i++)
        {
            maxi=max(maxi,++cnt[ color[i][j]   ] );
        }
        tot+= n-maxi;
    }
    ans=min(ans,tot);
}

void dfs(int x)
{
    if(x==n)
    {
        check();
        return;
    }
    for(int j=0;j<24;j++)
    {
        r[x]=j;
        dfs(x+1);
    }

}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        N=0;mp.clear();
        for0(i,n)
        {
            for0(j,6)
            {
               scanf("%s",s);
               cube[i][j]=ID(s);
            }
        }
        ans=INF;
        r[0]=0;//第一个立方体用哪种摆放方式随意
        dfs(1);
        printf("%d\n",ans);
    }
   return 0;
}
/**
时间复杂度O(24^(n-1) *n*6)
**/




打表:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;

int L[6]={  4,0,2,3,5,1    };
int U[6]={  2,1,5,0,4,3    };//原来是0,现在向上翻转了,到了位置2


void  rot(int *p)//p[0]表示编号为0的立方体现在在何处。
{
    int q[6];
    memcpy(q,p,sizeof q);
    for0(i,6)
    {
        p[i]= L[ q[i] ] ;//某颜色的新位置=原位置经过L()映射
    }
}


void up(int *p)
{
    int q[6];
    memcpy(q,p,sizeof q);//这里必须写 memcpy(q,p,sizeof q);不能写sizeof p,因为p是指针
    for0(i,6)
    {
        p[i]= U[ q[i] ] ;
    }
}

void out(int *p)
{
    printf("{");

    for0(i,6)
    {
        if(i)  printf(",");
        printf("%d",p[i]);
    }

    printf("}");
}
int main()
{
    int p0[]={0,1,2,3,4,5};
    printf("int cube24[24][6]={\n");
    for(int i=0;i<6;i++ )
    {

        int p[6];
        memcpy(p,p0,sizeof p0);
        if(i==0)  {  up(p);     }

        else if(i==1) { rot(p);up(p);  }
        else if(i==2)  {   }
        else if(i==3)  {  up(p);up(p);                     }
        else if(i==4){  rot(p); rot(p);rot(p);up(p); }
        else if(i==5){  up(p);up(p);up(p); }

        for0(j,4)
        {
            if(i||j)  printf(",");
            out(p);
            rot(p);
        }

    }
    printf("\n};\n");


   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值