zoukankan      html  css  js  c++  java
  • 中国象棋将帅问题

    问题:输出中国象棋将帅所有合法位置,且只能用一个字节存储变量。

    分析:此问题的本质是搜索、剪枝,只用一个字节存储变量,意义是要进行位运算,或者用C语言中结构体变量中设定的可以使用结构体变量的低4位或者高四位。

    互斥的条件是:不能再同一列即可。

    第一步:将问题形式化,给这9个位置编号,这是重要的,类似于表征问题的解空间。

    第二步:用位或者结构体变量,或者直接根据数字特征来剪枝解空间。位运算中往往要用到逻辑运算来改变各个位的值。

    所以产生下面三种解法:

    #include "stdafx.h"
    #include<stdio.h>
    
    //宏定义
    #define HALF_BITS_LENGTH	4	//记忆存储单元的一半
    #define FULLMASK			255	//全部bit的掩码
    #define LMASK	(FULLMASK<<HALF_BITS_LENGTH)	//左bits的掩码
    #define RMASK	(FULLMASK>>HALF_BITS_LENGTH)	//右bits的掩码
    #define RSET(b,n)	(b=((LMASK&b)|(n)))	//将b的右边设置成n
    #define LSET(b,n)	(b=((RMASK&b)|((n)<<HALF_BITS_LENGTH)))	//将b左边设置成n
    #define RGET(b)	(RMASK&b)	//得到b的右边的值
    #define LGET(b)	((LMASK&b)>>HALF_BITS_LENGTH)	//得到b的左边的值
    #define GRIDW	3			//将帅移动范围的行宽度
    
    //解法一
    void Solve1()
    {
    	unsigned char b;
    	for(LSET(b,1);LGET(b)<=GRIDW*GRIDW;LSET(b,(LGET(b)+1)))
    		for(RSET(b,1);RGET(b)<=GRIDW*GRIDW;RSET(b,(RGET(b)+1)))
    			if(LGET(b)%GRIDW!=RGET(b)%GRIDW)
    				printf("A=%d, B=%d
    ",LGET(b),RGET(b));
    
    }
    
    //解法二
    void Solve2()
    {
    	unsigned int i=81;	//9*9=81种组合,搜索、剪枝
    
    	while(i--)
    	{
    		if(i/9%3==i%9%3)
    			continue;
    		printf("A=%d, B=%d
    ",i/9+1,i%9+1);
    	}
    }
    
    //解法三
    struct 
    {
    	unsigned char a:4;	//a使用结构体变量i的低4位
    	unsigned char b:4;	//b使用结构体变量i的高4位
    }i;
    void Solve3()
    {
    	for(i.a=1;i.a<=9;i.a++)
    		for(i.b=1;i.b<=9;i.b++)
    			if(i.a%3!=i.b%3)
    			printf("A=%d, B=%d
    ",i.a,i.b);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	printf("------------解法一----------:
    ");
    	Solve1();
    	printf("------------解法二----------:
    ");
    	Solve2();
    	printf("------------解法三----------:
    ");
    	Solve3();
    	return 0;
    }
    

    遇到的问题是:

    复杂宏定义的括号匹配问题,根据所有问题的解组合,一共有81中解,然后根据不在同一列的数字特征进行剪枝,是一个可取的方法,不过比较难以理解。

  • 相关阅读:
    Allegro PCB Design GXL (legacy) 使用slide无法将走线推挤到焊盘的原因
    OrCAD Capture CIS 16.6 导出BOM
    Altium Designer (17.0) 打印输出指定的层
    Allegro PCB Design GXL (legacy) 将指定的层导出为DXF
    Allegro PCB Design GXL (legacy) 设置十字大光标
    Allegro PCB Design GXL (legacy) 手动更改元器件引脚的网络
    magento产品导入时需要注意的事项
    magento url rewrite
    验证台湾同胞身份证信息
    IE8对css文件的限制
  • 原文地址:https://www.cnblogs.com/fistao/p/3171070.html
Copyright © 2011-2022 走看看