- #include "iostream"
- using namespace std;
- unsigned short int flips[16]={0xc800,0xe400,0x7200,0x3100,0x8c80,0x4e40,0x2720,0x1310,
- 0x08c8,0x04e4,0x0272,0x0131,0x008c,0x004e,0x0027,0x0013};
- int min1=16;
- unsigned short int poww2(int n)
- {
- int i=1;
- i=i<<n;
- return i;
- }
- void bsp(unsigned short int number,int step,int flip)
- {
- if(number==0||number==0xffff)
- {
- min1=(min1<flip?min1:flip);
- return ;
- }
- if(step>=16)return;
- bsp(number,step+1,flip);
- bsp(number^flips[step],step+1,flip+1);
- }
- int main()
- {
- int i=0;
- unsigned short int num=0;
- char x;
- while(i<16)
- {
- cin>>x;
- if(x=='b')
- num+=poww2(15-i);
- i++;
- }
- min1=16;
- bsp(num,0,0);
- if(min1==16)
- printf("Impossible/n");
- else printf("%d/n",min1);
- return 0;
- }
前两天没怎么做,卡在这道题上了,很是郁闷,觉得连这些基础的题都做不了。
后来觉得看看别人的做法,在网上看到了这位同学的博客:http://blog.sina.com.cn/s/blog_606e17490100f4n8.html
代码的思路比较清晰,比较容易看懂。
但是其中有一个问题我想了很长时间,就是为什么深度将16次作为上限。
后来在别人的帮助下终于想通了:
一共就16个格子 按17次的话 肯定有一个两次
一个格子在变换过程中按两次 相当于没按 没有意义
所以将16作为上限值。
==========================================华丽的分割============================================
2013-6-7
自己很久没有写算法的题目了。没有思路。参考了别人的总结。上面的代码简洁明了。
bsp的递归实现写的很棒,想起来数据结构老师曾经说过一句话: 要大胆地写递归。
这个题目,我联想到了人工智能中的产生式系统。
产生式系统的组成我还记得。
1)综合数据库
2)产生式规则集
3)控制策略
想来,大体框架就是:
DATA <---- 初始状态描述
until DATA 满足终止条件 , do;
begin
在规则集合中,选一条可用于DATA的规则R
DATA <----- R应用到DATA的结果
end
其中如何选取规则,就是控制策略的工作了。
根据上面的代码, 修改后AC:
Source Code
Problem: 1753 User: huntinux
Memory: 132K Time: 47MS
Language: C Result: Accepted
Source Code
#include <stdio.h>
// 代表16条翻转规则。翻转用亦或操作实现。
unsigned short int flips[16]={0xc800,0xe400,0x7200,0x3100,0x8c80,0x4e40,0x2720,0x1310,0x08c8,0x04e4,0x0272,0x0131,0x008c,0x004e,0x0027,0x0013};
int min = 16 + 1;
void bsp(unsigned short int number, int index, int flip)
{
if(number == 0x0000 || number == 0xffff){
min = (min > flip ? flip : min); // 记录最小的层数
return ;
}
if(index >= 16) return;
bsp(number, index + 1, flip); // 同层
bsp(number ^ flips[index], index + 1, flip + 1); //下一层 , 体现了宽度优先搜索
}
void get_number(unsigned short int *number)
{
int i;
char ch;
for(i = 0; i < 16; i++){
scanf("%c", &ch);
if('b' == ch) *number += (1 << (15 - i));
else if('\n' == ch) i--; // 去掉多余的回车的影响
}
}
int main()
{
unsigned short int number = 0;
get_number(&number);
bsp(number, 0, 0);
if(min <= 16) printf("%d\n", min);
else printf("Impossible\n");
return 0;
}