hdu3220 2010.3.1

来源:互联网 发布:浙江网络诈骗立案标准 编辑:程序博客网 时间:2024/06/09 14:01

hdu3220 2010.3.1

hdu 3220 Alice’s Cube

 

 

【关键字】

广度优先搜索+位运算+逆向思维

 

【摘要】

给定16个顶点的位置关系,每个点上都有一盏灯,灯有两种状态:开和关。当两盏灯相邻且状态不同时,可以交换他们的状态,称之为一次操作。给定16盏灯的起始状态和目标状态,求多少次操作可以达到目标状态。操作次数超过3时,输出more。

【正文】

1、题目描述

 

Alice’s Cube

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 170    Accepted Submission(s): 57

 

 

Problem Description

 

 

Alice has received a hypercube toy as her birthday present. Thishypercube has 16 vertices, numbered from 1 to 16, as illustrated below. Onevery 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. Youare allowed to switch the states of two adjacent light bulbs with differentstates (“on” to “off”, and “off” to “on”; specifically, swap their states) inone operation.

 

Given the initial state of the lights, yourtask is to calculate the minimum number of steps needed to achieve the targetstate, in which the light bulbs on the sub cube (1,2,3,4)-(5,6,7,8) are turnedoff, and the rest of them are turned on.

 

 

Input

There are multiple test cases. The firstline 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 ina single line, the i-th number is 1 meaning the light of the i-th vertex on thepicture is on, and otherwise it’s off.

 

 

Output

For every test cases output a number withcase number meaning the minimum steps needed to achieve the goal. If the numberis 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

2009 Asia Shanghai Regional Contest Host by DHU

 

 

Recommend

zhuweicong

 

2、算法分析

(1)用16位的二进制表示灯的状态。因为题中说超过3次操作,则输出“more”;且目标状态都是0000000011111111;而且是多组数据。所以考虑从目标状态做分别作0-3次操作,生成所有满足规则的状态,挂表,看测试数据是不是在表里,不在,就输出more。

(2)对于操作,交换哪两个点,对应的二进制位为1,其余为0。判断是否是规范的操作,按位与,两种不规范的操作:如果两位都是0的话,则按位与的结果是0;如果两位都是1的话,则按位与的结果是这个操作对应的数。对于规范的操作,把这个状态对应的数和此操作对应的数按位异或。

3、源码

#include <stdio.h>#include <string.h>#define TWON 17#define MAXM 32#define MAXN 10000int two[TWON]={0,32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1};int dic[33]={/*1100000000000000,1010000000000000,1000100000000000,1000000010000000,0101000000000000,0100010000000000,0100000001000000,0011000000000000,0010001000000000,0010000000100000,0001000100000000,0001000000010000,0000110000000000,0000101000000000,0000100000001000,0000010100000000,0000010000000100,0000001100000000,0000001000000010,0000000100000001,0000000011000000,0000000010100000,0000000010001000,0000000001010000,0000000001000100,0000000000110000,0000000000100010,0000000000010001,0000000000001100,0000000000001010,0000000000000101,0000000000000011*/0,49152,40960,34816,32896,20480,17408,16448,12288,8704,8224,4352,4112,3072,2560,2056,1280,1028,768,514,257,192,160,136,80,68,48,34,17,12,10,5,3};struct node{int value,num;}f[MAXN];int lf=0;int headnow,tailnow;int find(int x){int i;for(i=1;i<=lf;i++)if (f[i].value==x) return 0;return 1;}void build(){int i,j,x;for(i=headnow;i<=tailnow;i++){for(j=1;j<=32;j++)if ((((f[i].value)&(dic[j]))!=0)&&(((f[i].value)&(dic[j]))!=dic[j])){x=f[i].value^dic[j];if (find(x)){lf++;f[lf].value=x;f[lf].num=f[i].num+1;}}}headnow=tailnow+1;tailnow=lf;}void makeout(){int i;f[1].value=255;f[1].num=0;headnow=1;tailnow=1;lf=1;for(i=1;i<=3;i++)build();} void main(){makeout();char s[100],ch[10];int ans,flag,n=0,i,tt,k;scanf("%d",&tt);gets(s);for(k=1;k<=tt;k++){gets(s);n++;printf("Case #%d: ",n);ans=0;flag=0;for(i=0;i<=15;i++){ans=ans+(s[i*2]-48)*two[i+1];}for(i=1;i<=lf;i++)if (f[i].value==ans){printf("%d\n",f[i].num);flag=1;break;}if (!flag)printf("more\n");}}


0 0
原创粉丝点击