uvaLive 3401 Colored Cubes 暴力

来源:互联网 发布:学校网络整合营销策划 编辑:程序博客网 时间:2024/05/18 01:01





题意:给出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,现在向上翻转了,到了位置2void  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
原创粉丝点击