POJ 1753 : Flip Game

原文: http://blog.csdn.net/yl198753/article/details/6125187


Flip Game
[cpp] view plain copy
  1. #include "iostream"  
  2. using namespace std;  
  3. unsigned short int flips[16]={0xc800,0xe400,0x7200,0x3100,0x8c80,0x4e40,0x2720,0x1310,  
  4.               0x08c8,0x04e4,0x0272,0x0131,0x008c,0x004e,0x0027,0x0013};  
  5. int min1=16;  
  6. unsigned short int poww2(int n)  
  7. {  
  8.     int i=1;  
  9.     i=i<<n;  
  10.     return i;   
  11. }  
  12.   
  13. void bsp(unsigned short int number,int step,int flip)  
  14. {  
  15.     if(number==0||number==0xffff)  
  16.     {  
  17.         min1=(min1<flip?min1:flip);  
  18.         return ;  
  19.     }  
  20.     if(step>=16)return;  
  21.     bsp(number,step+1,flip);  
  22.     bsp(number^flips[step],step+1,flip+1);  
  23. }  
  24. int main()  
  25. {  
  26.     int i=0;  
  27.     unsigned short int num=0;  
  28.     char x;  
  29.     while(i<16)  
  30.     {  
  31.         cin>>x;  
  32.         if(x=='b')  
  33.         num+=poww2(15-i);  
  34.         i++;  
  35.     }  
  36.     min1=16;  
  37.     bsp(num,0,0);  
  38.     if(min1==16)  
  39.         printf("Impossible/n");  
  40.     else printf("%d/n",min1);  
  41.     return 0;  
  42. }  

前两天没怎么做,卡在这道题上了,很是郁闷,觉得连这些基础的题都做不了。

后来觉得看看别人的做法,在网上看到了这位同学的博客: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;
    }




你可能感兴趣的:(poj,1753)