HDU3220-Alice’s Cube

28 篇文章 0 订阅

Alice’s Cube

                                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                                                                        Total Submission(s): 1998    Accepted Submission(s): 668

Problem Description

Alice has received a hypercube toy as her birthday present. This hypercube has 16 vertices, numbered from 1 to 16, as illustrated below. On every vertex, there is a light bulb that can be turned on or off. Initially, eight of the light bulbs are turned on and the other eight are turned off. You are allowed to switch the states of two adjacent light bulbs with different states (“on” to “off”, and “off” to “on”; specifically, swap their states) in one operation.

Given the initial state of the lights, your task is to calculate the minimum number of steps needed to achieve the target state, in which the light bulbs on the sub cube (1,2,3,4)-(5,6,7,8) are turned off, and the rest of them are turned on.
 
Input
There are multiple test cases. The first line of the input contains an integer T, meaning the number of the test cases. There are about 13000 test cases in total.
For each test case there are 16 numbers in a single line, the i-th number is 1 meaning the light of the i-th vertex on the picture is on, and otherwise it’s off.
 
Output
For every test cases output a number with case number meaning the minimum steps needed to achieve the goal. If the number is larger than 3, you should output “more”.
 
Sample Input
  
  
3 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1
 
Sample Output
  
  
Case #1: 0 Case #2: 1 Case #3: more
 
Source

题意:给一个超级立方体(具体看题目中的图),16个点,每个点有4个相邻点,图中有标识。现在每个点安一个灯泡。一共16个灯泡,有8盏亮8盏灭,现在可以交换任意相邻的2盏状态不同的灯的状态。求最少多少步能使编号1-8的8个灯泡亮,其他的灭。

解题思路:不能直接爆搜,直接爆搜要TLE。当操作的步数大于3的时候就输出more,那么可以从终态枚举进行了三次操作所能达到的所有状态,用广搜直接使用vis数组来记录

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstring>
#include <map>

using namespace std;

int vis[1000000];
int check[20][20],cas;

void bfs()
{
    queue<int>q;
    char ch[17]="0000000011111111";
    int x=0;
    for(int i=0; i<16; i++)
    {
        if(ch[i]=='1')
            x|=(1<<i);
    }
    vis[x]=0;
    q.push(x);
    int pre,next;
    while(!q.empty())
    {
        pre=q.front();
        q.pop();
        for(int i=0; i<16; i++)
        {
            for(int j=0; j<16; j++)
            {
                if(check[i][j])
                {
                    next=pre;
                    int x1=pre&(1<<i);
                    int x2=pre&(1<<j);
                    if(x1==x2) continue;
                    next^=(1<<i);
                    next^=(1<<j);
                    if(vis[next]==-1)
                    {
                        vis[next]=vis[pre]+1;
                        if(vis[next]<3)
                            q.push(next);
                    }
                }
            }
        }
    }
}

int main()
{

    int t,a[20];
    cas=0;
    check[0][4]=check[0][1]=check[0][8]=check[0][2]=1;
    check[1][0]=check[1][3]=check[1][9]=check[1][5]=1;
    check[2][0]=check[2][6]=check[2][3]=check[2][10]=1;
    check[3][2]=check[3][1]=check[3][7]=check[3][11]=1;
    check[4][0]=check[4][6]=check[4][5]=check[4][12]=1;
    check[5][7]=check[5][13]=check[5][4]=check[5][1]=1;
    check[6][4]=check[6][7]=check[6][2]=check[6][14]=1;
    check[7][3]=check[7][6]=check[7][15]=check[7][5]=1;
    check[8][9]=check[8][0]=check[8][12]=check[8][10]=1;
    check[9][11]=check[9][1]=check[9][13]=check[9][8]=1;
    check[10][8]=check[10][14]=check[10][11]=check[10][2]=1;
    check[11][9]=check[11][15]=check[11][3]=check[11][10]=1;
    check[12][8]=check[12][14]=check[12][4]=check[12][13]=1;
    check[13][12]=check[13][5]=check[13][15]=check[13][9]=1;
    check[14][10]=check[14][12]=check[14][15]=check[14][6]=1;
    check[15][11]=check[15][14]=check[15][13]=check[15][7]=1;
    memset(vis,-1,sizeof vis);
    bfs();
    scanf("%d",&t);
    while(t--)
    {
        int x=0;
        for(int i=0; i<16; i++)
        {
            scanf("%d",&a[i]);
            if(a[i])
                x|=(1<<i);
        }
        if(vis[x]>=0) printf("Case #%d: %d\n",++cas,vis[x]);
        else printf("Case #%d: more\n",++cas);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值