<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[ACMaker的网上空间]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[]]></description>
<link>http://hi.baidu.com/fzbzchenxi</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[最近翻译了个东西]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/7f067f34a10962b1d0a2d3b2.html]]></link>
        <description><![CDATA[
		
		<p> </p>
<p>最近翻译了一个东西，是关于旋转卡壳及其应用的，翻译的不太好，大家将就着看吧，这个东西还是很强大的，很佩服做这个的大牛，思路很新颖啊！<img src="http://img.baidu.com/hi/jd/j_0043.gif"></p>
<p> </p>
<p>虽然基本上是人家十年前发表的东西，但是还是很实用的</p>
<p>我放到网盘上去了，大家想看的话可以去下，地址是<a href="http://acmaker.ys168.com/">http://acmaker.ys168.com/</a>，在我的资料下面的那个chm就是了。</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%CB%E3%B7%A8">算法</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/7f067f34a10962b1d0a2d3b2.html#comment">查看评论</a>]]></description>
        <pubDate>2008-10-07  21:50</pubDate>
        <category><![CDATA[算法]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/7f067f34a10962b1d0a2d3b2.html</guid>
</item>

<item>
        <title><![CDATA[转帖——关于Debug和Release之区别]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/94d22403bcdf38713912bbf9.html]]></link>
        <description><![CDATA[
		
		<div class="cnt" >
<p><font size="2">经常在 CSDN 上看见有人问 Debug 运行正常但 Release 失败的问题。以往的讨论往往是经验性的，并没有指出会这样的真正原因是什么，要想找出真正的原因通常要凭运气。最近我看了一些这方面的书，又参考了 CSDN 上的一些帖子，然后深入研究了一下关于二者的不同。以下是我的一些体会，拿来与大家共享。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
--------------------------------------<br>
本文主要包含如下内容：<br>
1. Debug 和 Release 编译方式的本质区别<br>
2. 哪些情况下 Release 版会出错<br>
2. 怎样&ldquo;调试&rdquo; Release 版的程序<br>
--------------------------------------</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   关于Debug和Release之本质区别的讨论</font></p>
<p><font size="2">一、Debug 和 Release 编译方式的本质区别</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  Debug 通常称为调试版本，它包含调试信息，并且不作任何优化，便于程序员调试程序。Release 称为发布版本，它往往是进行了各种优化，使得程序在代码大小和运行速度上都是最优的，以便用户很好地使用。Debug 和 Release 的真正秘密，在于一组编译选项。下面列出了分别针对二者的选项（当然除此之外还有其他一些，如/Fd /Fo，但区别并不重要，通常他们也不会引起 Release 版错误，在此不讨论）</font></p>
<p><font size="2">Debug 版本：<br>
/MDd /MLd 或 /MTd&nbsp;&nbsp;   使用 Debug runtime library(调试版本的运行时刻函数库)<br>
/Od&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   关闭优化开关<br>
/D &quot;_DEBUG&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   相当于 #define _DEBUG,打开编译调试代码开关(主要针对<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   assert函数)<br>
/ZI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   创建 Edit and continue(编辑继续)数据库，这样在调试过<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   程中如果修改了源代码不需重新编译<br>
/GZ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   可以帮助捕获内存错误<br>
/Gm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   打开最小化重链接开关，减少链接时间</font></p>
<p><font size="2">Release 版本：<br>
/MD /ML 或 /MT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   使用发布版本的运行时刻函数库<br>
/O1 或 /O2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   优化开关，使程序最小或最快<br>
/D &quot;NDEBUG&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   关闭条件编译调试代码开关(即不编译assert函数)<br>
/GF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   合并重复的字符串，并将字符串常量放到只读内存，防止被修改</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   实际上，Debug 和 Release 并没有本质的界限，他们只是一组编译选项的集合，编译器只是按照预定的选项行动。事实上，我们甚至可以修改这些选项，从而得到优化过的调试版本或是带跟踪语句的发布版本。</font></p>
<p><font size="2">二、哪些情况下 Release 版会出错</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   有了上面的介绍，我们再来逐个对照这些选项看看 Release 版错误是怎样产生的</font></p>
<p><font size="2">1. Runtime Library：链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的 Runtime Library 包含了调试信息，并采用了一些保护机制以帮助发现错误，因此性能不如发布版本。编译器提供的 Runtime Library 通常很稳定，不会造成 Release 版错误；倒是由于 Debug 的 Runtime Library 加强了对错误的检测，如堆内存分配，有时会出现 Debug 有错但 Release 正常的现象。应当指出的是，如果Debug有错，即使 Release<br>
正常，程序肯定是有 Bug 的，只不过可能是 Release版的某次运行没有表现出来而已。</font></p>
<p><br>
<font size="2">2. 优化：这是造成错误的主要原因，因为关闭优化时源程序基本上是直接翻译的，而打开优化后编译器会作出一系列假设。这类错误主要有以下几种：</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  (1) 帧指针(Frame Pointer)省略（简称 FPO ）：在函数调用过程中，所有调用信息（返回地址、参数）以及自动变量都是放在栈中的。若函数的声明与实现不同（参数、返回值、调用方式），就会产生错误 &mdash;&mdash;&mdash;&mdash;但 Debug 方式下，栈的访问通过 EBP 寄存器保存的地址实现，如果没有发生数组越界之类的错误（或是越界&ldquo;不多&rdquo;），函数通常能正常执行；Release 方式下，优化会省略 EBP 栈基址指针，这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误，但如果用了强制类型转换，就不行了。你可以在 Release 版本中强制加入 /Oy- 编译选项来关掉帧指针省略，以确定是否此类错误。此类错误通常有：</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;   ● MFC 消息响应函数书写错误。正确的应为<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ON_MESSAGE 宏包含强制类型转换。防止这种错误的方法之一是重定义 ON_MESSAGE宏，把下列代码加到 stdafx.h 中（在#include &quot;afxwin.h&quot;之后）,函数原形错误时编译会报错<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   #undef ON_MESSAGE<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   #define ON_MESSAGE(message, memberFxn) \<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   { message, 0, 0, 0, AfxSig_lwl, \<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   (AFX_PMSG)(AFX_PMSGW)(static_cast&lt; LRESULT (AFX_MSG_CALL \<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   CWnd::*)(WPARAM, LPARAM) &gt; (&amp;memberFxn) },</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  (2) volatile 型变量：volatile 告诉编译器该变量可能被程序之外的未知方式修改（如系统、其他进程和线程）。优化程序为了使程序性能提高，常把一些变量放在寄存器中（类似于 register 关键字），而其他进程只能对该变量所在的内存进行修改，而寄存器中的值没变。如果你的程序是多线程的，或者你发现某个变量的值与预期的不符而你确信已正确 的设置了，则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上 volatile 试试。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  (3) 变量优化：优化程序会根据变量的使用情况优化变量。例如，函数中有一个未被使用的变量，在 Debug 版中它有可能掩盖一个数组越界，而在 Release 版中，这个变量很可能被优化调，此时数组越界会破坏栈中有用的数据。当然，实际的情况会比这复杂得多。与此有关的错误有：<br>
&nbsp;&nbsp;&nbsp;&nbsp;   ● 非法访问，包括数组越界、指针错误等。例如<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   void fn(void)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   int i;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   i = 1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   int a[4];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   int j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   j = 1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   a[-1] = 1;//当然错误不会这么明显，例如下标是变量<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   a[4] = 1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   j 虽然在数组越界时已出了作用域，但其空间并未收回，因而 i 和 j 就会掩盖越<br>
界。而 Release 版由于 i、j 并未其很大作用可能会被优化掉，从而使栈被破坏。</font></p>
<p><font size="2">3. _DEBUG 与 NDEBUG ：当定义了 _DEBUG 时，assert() 函数会被编译，而 NDEBUG 时不被编译。除此之外，VC++中还有一系列断言宏。这包括：</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   ANSI C 断言&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   void assert(int expression );<br>
&nbsp;&nbsp;&nbsp;   C Runtime Lib 断言 _ASSERT( booleanExpression );<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   _ASSERTE( booleanExpression );<br>
&nbsp;&nbsp;&nbsp;   MFC 断言&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ASSERT( booleanExpression );<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   VERIFY( booleanExpression );<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ASSERT_VALID( pObject );<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ASSERT_KINDOF( classname, pobject );<br>
&nbsp;&nbsp;&nbsp;   ATL 断言&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   ATLASSERT( booleanExpression );<br>
&nbsp;&nbsp;&nbsp;   此外，TRACE() 宏的编译也受 _DEBUG 控制。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  所有这些断言都只在 Debug版中才被编译，而在 Release 版中被忽略。唯一的例外是VERIFY() 。事实上，这些宏都是调用了 assert() 函数，只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码，而不只是布尔表达式（例如赋值、能改变变量值的函数调用 等），那么 Release 版都不会执行这些操作，从而造成错误。初学者很容易犯这类错误，查找的方法也很简单，因为这些宏都已在上面列出，只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外，有些高手可能还会加入 #ifdef _DEBUG 之类的条件编译，也要注意一下。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  顺便值得一提的是 VERIFY() 宏，这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查 Windows API 的返回值。有些人可能为这个原因而滥用 VERIFY() ，事实上这是危险的，因为 VERIFY() 违反了断言的思想，不能使程序代码和调试代码完全分离，最终可能会带来很多麻烦。因此，专家们建议尽量少用这个宏。</font></p>
<p><font size="2">4. /GZ 选项：这个选项会做以下这些事</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  (1) 初始化内存和变量。包括用 0xCC 初始化所有自动变量，0xCD ( Cleared Data) 初始化堆中分配的内存（即动态分配的内存，例如 new ），0xDD ( Dead Data ) 填充已被释放的堆内存（例如 delete ），0xFD( deFencde Data ) 初始化受保护的内存（debug 版在动态分配内存的前后加入保护内存以防止越界访问），其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大，作为指针是不可能的（而且 32 位系统中指<br>
针很少是奇数值，在有些系统中奇数的指针会产生运行时错误），作为数值也很少遇到，而且这些值也很容易辨认，因此这很有利于在 Debug 版中发现 Release 版才会遇到的错误。要特别注意的是，很多人认为编译器会用 0 来初始化变量，这是错误的（而且这样很不利于查找错误）。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   (2) 通过函数指针调用函数时，会通过检查栈指针验证函数调用的匹配性。（防止原形不匹配）</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   (3) 函数返回前检查栈指针，确认未被修改。（防止越界访问和原形不匹配，与第二项合在一起可大致模拟帧指针省略 FPO ）</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   通常 /GZ 选项会造成 Debug 版出错而 Release 版正常的现象，因为 Release 版中未初始化的变量是随机的，这有可能使指针指向一个有效地址而掩盖了非法访问。</font></p>
<p><font size="2">除此之外，/Gm /GF 等选项造成错误的情况比较少，而且他们的效果显而易见，比较容易发现。</font></p>
<p><font size="2">三、怎样&ldquo;调试&rdquo; Release 版的程序</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   遇到 Debug 成功但 Release 失败，显然是一件很沮丧的事，而且往往无从下手。如果你看了以上的分析，结合错误的具体表现，很快找出了错误，固然很好。但如果一时找不出，以下给出了一些在这种情况下的策略。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  1. 前面已经提过，Debug 和 Release 只是一组编译选项的差别，实际上并没有什么定义能区分二者。我们可以修改 Release 版的编译选项来缩小错误范围。如上所述，可以把 Release 的选项逐个改为与之相对的 Debug 选项，如 /MD 改为 /MDd、/O1 改为 /Od，或运行时间优化改为程序大小优化。注意，一次只改一个选项，看改哪个选项时错误消失，再对应该选项相关的错误，针对性地查找。这些选项在 Project\Settings... 中都可以直接通过列表选取，通常不要手动修改。由于以上的分析已相当全面，这个方法是最有效的。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;   2. 在编程过程中就要时常注意测试 Release 版本，以免最后代码太多，时间又很紧。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  3. 在 Debug 版中使用 /W4 警告级别，这样可以从编译器获得最大限度的错误信息，比如 if( i =0 )就会引起 /W4 警告。不要忽略这些警告，通常这是你程序中的 Bug 引起的。但有时 /W4 会带来很多冗余信息，如 未使用的函数参数 警告，而很多消息处理函数都会忽略某些参数。我们可以用<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   #progma warning(disable: 4702) //禁止<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   //...<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   #progma warning(default: 4702) //重新允许来暂时禁止某个警告，或使用<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   #progma warning(push, 3) //设置警告级别为 /W3<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   //...<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   #progma warning(pop) //重设为 /W4来暂时改变警告级别，有时你可以只在认为可疑的那一部分代码使用 /W4。</font></p>
<p><font size="2">&nbsp;&nbsp;&nbsp;  4.你也可以像 Debug 一样调试你的 Release 版，只要加入调试符号。在 Project/Settings... 中，选中 Settings for &quot;Win32 Release&quot;，选中 C/C++ 标签，Category 选General，Debug Info 选 Program Database。再在 Link 标签 Project options 最后加上 &quot;/OPT:REF&quot; (引号不要输)。这样调试器就能使用 pdb 文件中的调试符号。但调试时你会发现断点很难设置，变量也很难找到&mdash;&mdash;这些都被优化过了。不过令人庆幸的是，Call Stack 窗口仍然工作正常，即使帧指针被优化，栈信息（特别是返回地址）仍然能找到。这对定位错误很有帮助。</font></p>
</div> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/94d22403bcdf38713912bbf9.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%CB%E3%B7%A8">算法</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/94d22403bcdf38713912bbf9.html#comment">查看评论</a>]]></description>
        <pubDate>2008-09-08  15:39</pubDate>
        <category><![CDATA[算法]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/94d22403bcdf38713912bbf9.html</guid>
</item>

<item>
        <title><![CDATA[以前一直认为很神奇——Pascal的编译开关]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/664ca9ec340f4cd42e2e2155.html]]></link>
        <description><![CDATA[
		
		<table class="FCK__ShowTableBorders" width="740" border="0">
    <tbody>
        <tr>
            <td nowrap="nowrap">
            <div align="center">字母</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">缺省值</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">类型</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">实模式</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">保护模式</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">Windows</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">含义</div>
            </td>
            <td nowrap="nowrap" colspan="2">
            <div align="center">具体含义</div>
            </td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">A</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">A+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">按字地址对齐</div>
            </td>
            <td>
            <p>+</p>
            </td>
            <td width="100%">所有大于1字节的变量或类型常数均从偶地址开始存放。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">变量或类型常数均简单地放在下一可用地址。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">B</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">B-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">布尔计值控制</div>
            </td>
            <td>
            <p>+</p>
            </td>
            <td width="100%">执行完全布尔计值。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">执行短路布尔计值。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">D</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">D+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">调试信息开关</div>
            </td>
            <td>+</td>
            <td width="100%">将调试信息保存在一个行号表中，以供当运行出错时指示错处。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不产生调试信息行号表。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">E</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">E+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">浮点运算仿真</div>
            </td>
            <td>+</td>
            <td width="100%">不出现8087数字协处理器时运算允许用运行库仿真。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">必须有8087数字协处理器才能进行浮点运算。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">F</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">F-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">强制远程调用</div>
            </td>
            <td>+</td>
            <td width="100%">对子程序的调用总是远程调用。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">由Pascal自动选择对子程序的调用方式&mdash;&mdash;远程调用或近程调用。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">G</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">G-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">产生286代码</div>
            </td>
            <td>+</td>
            <td width="100%">编译器使用80286的附加指令以改善代码生成，但所编译的代码不能在8088或8086上运行。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">编译器只产生通常的8086指令。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">I</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">I+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">I/O出错检查</div>
            </td>
            <td>+</td>
            <td width="100%">由系统执行I/O出错检查。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">系统不执行I/O出错检查。</td>
        </tr>
        <tr>
            <td nowrap="nowrap">
            <div align="center">K</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">K+</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap">
            <div align="center"> </div>
            </td>
            <td nowrap="nowrap">
            <div align="center"> </div>
            </td>
            <td nowrap="nowrap">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap">
            <div align="center"> </div>
            </td>
            <td colspan="2"> </td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">L</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">L+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部符号开关</div>
            </td>
            <td>+</td>
            <td width="100%">产生某一模块的局部符号信息，使IDE可检查和修改模块的局部变量。如果调试信息开关置为{$D-}，则忽略{$L+}编译指示。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不产生某一模块的局部符号信息。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">N</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">N-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">数字协处理器</div>
            </td>
            <td>+</td>
            <td width="100%">使用数字协处理器，以硬件实现各类实型数运算。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不使用数字协处理器，实型数运算以软件实现。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">O</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">O-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center"> </div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center"> </div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">产生覆盖代码</div>
            </td>
            <td>+</td>
            <td width="100%">控制产生覆盖代码。经常与强制远调用编译指示{$F+}连用，以满足覆盖管理程序远程调用的要求。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不产生覆盖代码。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">P</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">P-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">不定长字串参</div>
            </td>
            <td>+</td>
            <td width="100%">string类型的字符串实参不预先确定最大长度，调用子程序时自动设为与实际参数类型一致。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不使用不定长字符串参数，与旧版本兼容。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">Q</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">Q-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">整数溢出检查</div>
            </td>
            <td>+</td>
            <td width="100%">整数运算检查溢出错误。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">整数运算不检查溢出。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">R</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">R-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">下标范围检查</div>
            </td>
            <td>+</td>
            <td width="100%">对运行时所有数组和字符串的下标表达式检查其值是否越界，并对标量和子界的测试值检查是否在指定范围内。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不执行上述检查。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">S</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">S+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">栈空间域检查</div>
            </td>
            <td>+</td>
            <td width="100%">在每次子程序调用前检查是否有足够的栈空间。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不执行上述检查。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">T</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">T-</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">指针类型检查</div>
            </td>
            <td>+</td>
            <td width="100%">@操作返回结果类型为类型指针。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">@操作返回结果类型为无类型指针。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">V</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">V+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">串长匹配检查</div>
            </td>
            <td>+</td>
            <td width="100%">对于在子程序中作为变量参数传递的字符串类型进行严格检查，要求实在参数与形式参数属于同一命名类型，即字符串长度必须一致。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不进行串长匹配检查，即允许实在参数与形式参数类型中的字符串长度不匹配。</td>
        </tr>
        <tr>
            <td nowrap="nowrap">
            <div align="center">W</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">W+</div>
            </td>
            <td nowrap="nowrap">
            <div align="center">局部</div>
            </td>
            <td nowrap="nowrap">
            <div align="center"> </div>
            </td>
            <td nowrap="nowrap">
            <div align="center"> </div>
            </td>
            <td nowrap="nowrap">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap">
            <div align="center"> </div>
            </td>
            <td colspan="2"> </td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">X</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">X+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">扩充词法开关</div>
            </td>
            <td>+</td>
            <td width="100%">函数调用可用语句形式表示，此时函数结果值可予抛弃。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">函数调用按通常形式，只能出现在表达式中。</td>
        </tr>
        <tr>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">Y</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">Y+</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">全程</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">√</div>
            </td>
            <td nowrap="nowrap" rowspan="2">
            <div align="center">符号索引信息</div>
            </td>
            <td>+</td>
            <td width="100%">把单元中的符号信息记录在单元编译文件中，供IDE浏览器使用。</td>
        </tr>
        <tr>
            <td>-</td>
            <td width="100%">不记录单元中的符号信息。</td>
        </tr>
    </tbody>
</table> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/664ca9ec340f4cd42e2e2155.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%C9%A8%C3%A4">扫盲</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/664ca9ec340f4cd42e2e2155.html#comment">查看评论</a>]]></description>
        <pubDate>2008-05-25  22:19</pubDate>
        <category><![CDATA[扫盲]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/664ca9ec340f4cd42e2e2155.html</guid>
</item>

<item>
        <title><![CDATA[Visual Studio系列]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/edb8508b3092ddd6fd1f10b1.html]]></link>
        <description><![CDATA[
		
		<p>既然扫盲就多来点，Visual Studio平时经常使用，还是百度百科上查到的资料，还真是什么都有，真好！~~~~~~~~~~~~~~~~~~~~~~<img src="http://img.baidu.com/hi/tsj/t_0002.gif"></p>
<p><img style="display: none" src="http://imgcache.qq.com/ac/qzone_v4/b.gif">Visual Studio 是微软公司推出的开发环境。是目前最流行的 Windows 平台应用程序开发环境。目前已经开发到 9.0 版本，也就是 Visual Studio 2008。 <br>
Visual Studio 可以用来创建 Windows 平台下的 Windows 应用程序和网络应用程序，也可以用来创建网络服务、智能设备应用程序和 Office 插件。 <br>
1998 年，微软公司发布了 Visual Studio 6.0。所有开发语言的开发环境版本均升至 6.0。这也是 Visual Basic 最后一次发布，从下一个版本 (7.0) 开始，Microsoft Basic 进化成了一种新的面向对象的语言：Microsoft Basic.NET。由于微软公司对于 Sun 公司 Java 语言扩充导致与 Java 虚拟机不兼容而 Sun 被告上法庭，微软在后续的 Visual Studio 中不再包括面向 Java 虚拟机的开发环境。 <br>
2002 年，随着 .NET 口号的提出与 Windows XP / Office XP 的发布，微软发布了 Visual Studio .NET（内部版本号为 7.0）。在这个版本的 Visual Studio 中，微软剥离了 Visual FoxPro 作为一个单独的开发环境以 Visual FoxPro 7.0 单独销售，同时取消了 Visual InterDev。与此同时，微软引入了建立在 .NET 框架上（版本1.0）的托管代码机制以及一门新的语言 C# （读作 C Sharp，意为 C++++）。C# 是一门建立在 C++ 和 Java 基础上的现代语言，是编写 .NET 框架的语言。 <br>
.NET 的通用语言框架机制（Common Language Runtime, CLR），其目的是在同一个项目中支持不同的语言所开发的组件。所有 CLR 支持的代码都会被解释成为 CLR 可执行的机器代码然后运行。 <br>
Visual Basic、Visual C++ 都被扩展为支持托管代码机制的开发环境，且 Visual Basic .NET更是从 Visual Basic 脱胎换骨，彻底支持面向对象的编程机制。而 Visual J++ 也变为 Visual J#。后者仅语法同 Java 相同，但是面向的不是 Java 虚拟机，而是 .NET Framework。 <br>
2003 年，微软对 Visual Studio 2002 进行了部分修订，以 Visual Studio 2003 的名义发布（内部版本号为 7.1）。Visio 作为使用统一建模语言（UML）架构应用程序框架的程序被引入，同时被引入的还包括移动设备支持和企业模版。.NET 框架也升级到了 1.1。 <br>
2005 年，微软发布了 Visual Studio 2005。.NET 字眼从各种语言的名字中被抹去，但是这个版本的 Visual Studio 仍然还是面向 .NET 框架的（版本2.0）。它同时也能开发跨平台的应用程序，如开发使用微软操作系统的手机的程序等。总体来说是一个非常庞大的软件，甚至包含代码测试功能。 <br>
这个版本的 Visual Studio 包含有众多版本，分别面向不同的开发角色。同时还永久提供免费的 Visual Studio Express 版本。 <br>
随着即将发布的 Windows Vista （内部名称：Longhorn) 和 Office 2007，Visual Studio 9 也渐渐浮出水面。Visual Studio 9 目前可以确定的是支持建立于 DHTML 基础上的 AJax 技术，这种微软在 Visual InterDev 时代提出的基于异步的客户端动态网页技术在当年并没有像微软预期中的那么流行起来，反而随着 GMail 等应用而东山再起，渐渐成为主流网络应用之一。同时 Visual Studio 9 会强化对于数据库的支持以及微软新的基于工作流（Workflow）的编程模型。预计为了保持与 Office 系列的统一，Visual Studio 9 的名称为 Visual Studio 2007。<br>
<br>
创建满足关键性要求的多层次的智能客户端、Web、移动或基于Microsoft Office的应用程序。<br>
<br>
使用Visual Studio 2005, 专业开发人员能够： <br>
<br>
使用改进后的可视化设计工具、编程语言和代码编辑器，享受高效率的开发环境 <br>
<br>
在统一的开发环境中，开发并调试多层次的服务器应用程序 <br>
<br>
使用集成的可视化数据库设计和报告工具，创建SQL Server 2005解决方案 <br>
<br>
使用Visual Studio SDK创建可以扩展Visual Studio IDE的工具 <br>
<br>
Microsoft为单独工作或在小型团队中的专业开发人员提供了两种选择，Visual Studio 2005 Professional Edition和用于Microsoft Office系统的Visual Studio 2005工具。每种版本都在标准版的特性上进行了扩展，包括用于远程服务程序开发和调试、SQL Server2005开发的工具，以及完整的、没有限制的开发环境。每种产品都可以单独购买或打包定购。 <br>
<br>
专业开发人员喜欢自由的使用.NET Framework 2.0，它是一种稳健的、功能齐备的开发环境，支持创建扩展Visual Studio集成开发环境的工具。 <br>
<br>
Visual Studio 2005 Professional Editions Features <br>
<br>
Visual Studio 2005 Professional with MSDN Premium Subscription* Visual Studio 2005 Professional with MSDN Professional Subscription* Visual Studio 2005 Professional Visual Studio 2005 Tools for the Microsoft Office System <br>
<br>
Language support Visual Basic, C#, C++, J# Visual Basic, C#, C++, J# Visual Basic, C#, C++, J# Visual Basic, C# <br>
<br>
Windows Forms Projects <br>
<br>
Web Projects <br>
<br>
Mobile Projects <br>
<br>
64 Bit support <br>
<br>
Enterprise templates <br>
<br>
Class Designer <br>
<br>
Server Explorer Full Full Full Full <br>
<br>
Excel, Word, InfoPath Projects <br>
<br>
Visio-based modeling <br>
<br>
Visual Source Safe <br>
<br>
SQL Server Developer Edition <br>
<br>
Operating Systems - Development and Test <br>
<br>
Servers - Development and Test <br>
<br>
Virtual PC <br>
<br>
Access Developer Extensions <br>
<br>
Office, InfoPath, OneNote, Visio, Project, MapPoint</p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/edb8508b3092ddd6fd1f10b1.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%C9%A8%C3%A4">扫盲</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/edb8508b3092ddd6fd1f10b1.html#comment">查看评论</a>]]></description>
        <pubDate>2008-05-23  23:45</pubDate>
        <category><![CDATA[扫盲]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/edb8508b3092ddd6fd1f10b1.html</guid>
</item>

<item>
        <title><![CDATA[关于匈牙利命名法（来自百度百科）]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/e893fd2ed1bdee554fc226aa.html]]></link>
        <description><![CDATA[
		
		<p>个人来说不太用，因为用的时候少，都是做ACM的，但是我相信会用到，先留着此文<img src="http://img.baidu.com/hi/jd/j_0043.gif"></p>
<p>以下是正文：</p>
<p>匈牙利命名法 <br>
<br>
匈牙利命名法是一种编程时的命名规范。基本原则是：变量名＝属性＋类型＋对象描述，其中每一对象的名称都要求有明确含义，可以取对象名字全称或名字的一部分。命名要基于容易记忆容易理解的原则。保证名字的连贯性是非常重要的。<br>
<br>
举例来说，表单的名称为form，那么在匈牙利命名法中可以简写为frm，则当表单变量名称为Switchboard时，变量全称应该为 frmSwitchboard。这样可以很容易从变量名看出Switchboard是一个表单，同样，如果此变量类型为标签，那么就应命名成 lblSwitchboard。可以看出，匈牙利命名法非常便于记忆，而且使变量名非常清晰易懂，这样，增强了代码的可读性，方便各程序员之间相互交流代码。 <br>
<br>
据说这种命名法是一位叫 Charles Simonyi 的匈牙利程序员发明的，后来他在微软呆了几年，于是这种命名法就通过微软的各种产品和文档资料向世界传播开了。现在，大部分程序员不管自己使用什么软件进行开发，或多或少都使用了这种命名法。这种命名法的出发点是把量名变按：属性+类型+对象描述的顺序组合起来，以使程序员作变量时对变量的类型和其它属性有直观的了解，下面是HN变量命名规范，其中也有一些是我个人的偏向： <br>
<br>
属性部分 <br>
全局变量 <br>
g_ <br>
常量 <br>
c_ <br>
c++类成员变量 <br>
m_ <br>
静态变量 <br>
s_ <br>
<br>
类型部分 <br>
指针 <br>
p <br>
函数 <br>
fn <br>
无效 <br>
v <br>
句柄 <br>
h <br>
长整型 <br>
l <br>
布尔 <br>
b <br>
浮点型（有时也指文件） <br>
f <br>
双字 <br>
dw <br>
字符串 <br>
sz <br>
短整型 <br>
n <br>
双精度浮点 <br>
d <br>
计数 <br>
c（通常用cnt） <br>
字符 <br>
ch（通常用c） <br>
整型 <br>
i（通常用n） <br>
字节 <br>
by <br>
字 <br>
w <br>
实型 <br>
r <br>
无符号 <br>
u <br>
<br>
描述部分 <br>
最大 <br>
Max <br>
最小 <br>
Min <br>
初始化 <br>
Init <br>
临时变量 <br>
T（或Temp） <br>
源对象 <br>
Src <br>
目的对象 <br>
Dest <br>
<br>
<br>
这里顺便写几个例子： <br>
hwnd ： h 是类型描述，表示句柄， wnd 是变量对象描述，表示窗口，所以 hwnd 表示窗口句柄； <br>
pfnEatApple ： pfn 是类型描述，表示指向函数的指针， EatApple 是变量对象描述，所以它表示 <br>
指向 EatApple 函数的函数指针变量。 <br>
g_cch ： g_ 是属性描述，表示全局变量，c 和 ch 分别是计数类型和字符类型，一起表示变量类 <br>
型，这里忽略了对象描述，所以它表示一个对字符进行计数的全局变量。 <br>
上面就是HN命名法的一般规则。 <br>
<br>
<br>
小结:匈牙利命名法 <br>
<br>
匈牙利命名法 <br>
<br>
<br>
MFC、句柄、控件及结构的命名规范 Windows类型 样本变量 MFC类 样本变量 <br>
HWND hWnd； CWnd* pWnd； <br>
HDLG hDlg； CDialog* pDlg； <br>
HDC hDC； CDC* pDC； <br>
HGDIOBJ hGdiObj； CGdiObject* pGdiObj； <br>
HPEN hPen； CPen* pPen； <br>
HBRUSH hBrush； CBrush* pBrush； <br>
HFONT hFont； CFont* pFont； <br>
HBITMAP hBitmap； CBitmap* pBitmap； <br>
HPALETTE hPaltte； CPalette* pPalette； <br>
HRGN hRgn； CRgn* pRgn； <br>
HMENU hMenu； CMenu* pMenu； <br>
HWND hCtl； CState* pState； <br>
HWND hCtl； CButton* pButton； <br>
HWND hCtl； CEdit* pEdit； <br>
HWND hCtl； CListBox* pListBox； <br>
HWND hCtl； CComboBox* pComboBox； <br>
HWND hCtl； CScrollBar* pScrollBar； <br>
HSZ hszStr； CString pStr； <br>
POINT pt； CPoint pt； <br>
SIZE size； CSize size； <br>
RECT rect； CRect rect； <br>
<br>
<br>
一般前缀命名规范 前缀 类型 实例 <br>
C 类或结构 CDocument，CPrintInfo <br>
m_ 成员变量 m_pDoc，m_nCustomers <br>
<br>
<br>
变量命名规范 前缀 类型 描述 实例 <br>
ch char 8位字符 chGrade <br>
ch TCHAR 如果_UNICODE定义，则为16位字符 chName <br>
b BOOL 布尔值 bEnable <br>
n int 整型（其大小依赖于操作系统） nLength <br>
n UINT 无符号值（其大小依赖于操作系统） nHeight <br>
w WORD 16位无符号值 wPos <br>
l LONG 32位有符号整型 lOffset <br>
dw DWORD 32位无符号整型 dwRange <br>
p * 指针 pDoc <br>
lp FAR* 远指针 lpszName <br>
lpsz LPSTR 32位字符串指针 lpszName <br>
lpsz LPCSTR 32位常量字符串指针 lpszName <br>
lpsz LPCTSTR 如果_UNICODE定义，则为32位常量字符串指针 lpszName <br>
h handle Windows对象句柄 hWnd <br>
lpfn callback 指向CALLBACK函数的远指针 <br>
<br>
<br>
前缀 符号类型 实例 范围 <br>
IDR_ 不同类型的多个资源共享标识 IDR_MAIINFRAME 1～0x6FFF <br>
IDD_ 对话框资源 IDD_SPELL_CHECK 1～0x6FFF <br>
HIDD_ 对话框资源的Help上下文 HIDD_SPELL_CHECK 0x20001～0x26FF <br>
IDB_ 位图资源 IDB_COMPANY_LOGO 1～0x6FFF <br>
IDC_ 光标资源 IDC_PENCIL 1～0x6FFF <br>
IDI_ 图标资源 IDI_NOTEPAD 1～0x6FFF <br>
ID_ 来自菜单项或工具栏的命令 ID_TOOLS_SPELLING 0x8000～0xDFFF <br>
HID_ 命令Help上下文 HID_TOOLS_SPELLING 0x18000～0x1DFFF <br>
IDP_ 消息框提示 IDP_INVALID_PARTNO 8～0xDEEF <br>
HIDP_ 消息框Help上下文 HIDP_INVALID_PARTNO 0x30008～0x3DEFF <br>
IDS_ 串资源 IDS_COPYRIGHT 1～0x7EEF <br>
IDC_ 对话框内的控件 IDC_RECALC 8～0xDEEF <br>
<br>
<br>
Microsoft MFC宏命名规范 名称 类型 <br>
_AFXDLL 唯一的动态连接库（Dynamic Link Library，DLL）版本 <br>
_ALPHA 仅编译DEC Alpha处理器 <br>
_DEBUG 包括诊断的调试版本 <br>
_MBCS 编译多字节字符集 <br>
_UNICODE 在一个应用程序中打开Unicode <br>
AFXAPI MFC提供的函数 <br>
CALLBACK 通过指针回调的函数 <br>
<br>
<br>
库标识符命名法 标识符 值和含义 <br>
u ANSI（N）或Unicode（U） <br>
d 调试或发行：D = 调试；忽略标识符为发行。 <br>
<br>
<br>
静态库版本命名规范 库 描述 <br>
NAFXCWD.LIB 调试版本：MFC静态连接库 <br>
NAFXCW.LIB 发行版本：MFC静态连接库 <br>
UAFXCWD.LIB 调试版本：具有Unicode支持的MFC静态连接库 <br>
UAFXCW.LIB 发行版本：具有Unicode支持的MFC静态连接库 <br>
<br>
<br>
动态连接库命名规范 名称 类型 <br>
_AFXDLL 唯一的动态连接库（DLL）版本 <br>
WINAPI Windows所提供的函数 <br>
<br>
<br>
Windows.h中新的命名规范 类型 定义描述 <br>
WINAPI 使用在API声明中的FAR PASCAL位置，如果正在编写一个具有导出API人口点的DLL，则可以在自己的API中使用该类型 <br>
CALLBACK 使用在应用程序回叫例程，如窗口和对话框过程中的FAR PASCAL的位置 <br>
LPCSTR 与LPSTR相同，只是LPCSTR用于只读串指针，其定义类似（const char FAR*） <br>
UINT 可移植的无符号整型类型，其大小由主机环境决定（对于Windows NT和Windows 9x为32位）；它是unsigned int的同义词 <br>
LRESULT 窗口程序返回值的类型 <br>
LPARAM 声明lParam所使用的类型，lParam是窗口程序的第四个参数 <br>
WPARAM 声明wParam所使用的类型，wParam是窗口程序的第三个参数 <br>
LPVOID 一般指针类型，与（void *）相同，可以用来代替LPSTR<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
抨击匈牙利命名法<br>
<br>
匈牙利命名法是一种编程时的命名规范。命名规范是程序书写规范中最重要也是最富争议的地方，自古乃兵家必争之地。命名规范有何用？四个字：名正言顺。用二分法，命名规范分为好的命名规范和坏的命名规范，也就是说名正言顺的命名规范和名不正言不顺的命名规范。好的舞鞋是让舞者感觉不到其存在的舞鞋，坏的舞鞋是让舞者带着镣铐起舞。一个坏的命名规范具有的破坏力比一个好的命名规范具有的创造力要大得多。<br>
<br>
本文要证明的是：匈牙利命名法是一个坏的命名规范。本文的作用范围为静态强类型编程语言。本文的分析范本为C语言和C++语言。下文中的匈法为匈牙利命名法的简称。<br>
<br>
一 匈牙利命名法的成本<br>
<br>
匈法的表现形式为给变量名附加上类型名前缀，例如：nFoo,szFoo,pFoo,cpFoo分别表示整型变量，字符串型变量，指针型变量和常指针型变量。可以看出，匈法将变量的类型信息从单一地点（声明变量处）复制到了多个地点（使用变量处），这是冗余法。冗余法的成本之一是要维护副本的一致性。这个成本在编写和维护代码的过程中需要改变变量的类型时付出。冗余法的成本之二是占用了额外的空间。一个优秀的书写者会自觉地遵从一个法则：代码最小组织单位的长度以30个自然行以下为宜，如果超过50行就应该重新组织。一个变量的书写空间会给这一法则添加不必要的难度。<br>
<br>
二 匈牙利命名法的收益<br>
<br>
这里要证明匈牙利命名法的收益是含糊的，无法预期的。<br>
<br>
范本1：strcpy(pstrFoo,pcstrFoo2) Vs strcpy(foo,foo2)<br>
匈法在这里有什么收益呢？我看不到。没有一个程序员会承认自己不知道strcpy函数的参数类型吧。<br>
<br>
范本2：unknown_function(nFoo) Vs unknown_function(foo)<br>
匈法在这里有什么收益呢？我看不到。对于一个不知道确定类型的函数，程序员应该去查看该函数的文档，这是一种成本。使用匈法的唯一好处是看代码的人知道这个函数要求一个整型参数，这又有什么用处呢？函数是一种接口，参数的类型仅仅是接口中的一小部分。诸如函数的功能、出口信息、线程安全性、异常安全性、参数合法性等重要信息还是必须查阅文档。<br>
<br>
范本3：nFoo=nBar Vs foo=bar<br>
匈法在这里有什么收益呢？我看不到。使用匈法的唯一好处是看代码的人知道这里发生了一个整型变量的复制动作，听起来没什么问题，可以安心睡大觉了。如果他看到的是nFoo=szBar，可能会从美梦中惊醒。且慢，事情真的会是这样吗？我想首先被惊醒的应该是编译器。另一方面，nFoo=nBar只是在语法上合法而已，看代码的人真正关心的是语义的合法性，匈法对此毫无帮助。另一方面，一个优秀的书写者会自觉地遵从一个法则：代码最小组织单位中的临时变量以一两个为宜，如果超过三个就应该重新组织。结合前述第一个法则，可以得出这样的结论：易于理解的代码本身就应该是易于理解的，这是代码的内建高质量。好的命名规范对内建高质量的助益相当有限，而坏的命名规范对内建高质量的损害比人们想象的要大。<br>
<br>
三 匈牙利命名法的实施<br>
<br>
这里要证明匈牙利命名法在C语言是难以实施的，在C++语言中是无法实施的。从逻辑上讲，对匈法的收益做出否定的结论以后，再来论证匈法的可行性，是画蛇添足。不过有鉴于小马哥曾让已射杀之敌死灰复燃，我还是再踏上一支脚为妙。<br>
<br>
前面讲过，匈法是类型系统的冗余，所以实施匈法的关键是我们是否能够精确地对类型系统进行复制。这取决于类型系统的复杂性。<br>
<br>
先来看看C语言：<br>
<br>
1.内置类型：int,char,float,double 复制为 n,ch,f,d？好像没有什么问题。不过谁来告诉我void应该怎么表示？<br>
2.组合类型：array,union,enum,struct 复制为 a,u,e,s？好像比较别扭。<br>
这里的难点不是为主类型取名，而是为副类型取名。an表示整型数组？sfoo,sbar表示结构foo，结构bar？ausfoo表示联合结构foo数组？累不累啊。<br>
3.特殊类型：pointer。pointer在理论上应该是组合类型，但是在C语言中可以认为是内置类型，因为C语言并没有非常严格地区分不同的指针类型。下面开始表演：pausfoo表示联合结构foo数组指针？ppp表示指针的指针的指针？<br>
<br>
噩梦还没有结束，再来看看类型系统更阿为丰富的C++语言：<br>
<br>
1.class：如果说C语言中的struct还可以用stru搪塞过去的话，不要梦想用cls来搪塞C++中的class。严格地讲，class根本就并不是一个类型，而是创造类型的工具，在C++中，语言内置类型的数量和class创造的用户自定义类型的数量相比完全可以忽略不计。stdvectorFoo表示标准库向量类型变量Foo？疯狂的念头。<br>
2.命名空间：boostfilesystemiteratorFoo，表示boost空间filesystem子空间遍历目录类型变量Foo？程序员要崩溃了。<br>
3.模板：你记得std::map&lt;std::string,std::string&gt;类型的确切名字吗？我是记不得了，好像超过255个字符，还是饶了我吧。<br>
4.模板参数：template &lt;class T, class BinaryPredicate&gt;const T&amp; max(const T&amp; a, const T&amp; b, BinaryPredicate comp) 聪明的你，请用匈法为T命名。上帝在发笑。<br>
5.类型修饰：static,extern,mutable,register,volatile,const,short,long,unsigned 噩梦加上修饰是什么？还是噩梦。</p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/e893fd2ed1bdee554fc226aa.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%C9%A8%C3%A4">扫盲</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/e893fd2ed1bdee554fc226aa.html#comment">查看评论</a>]]></description>
        <pubDate>2008-05-23  23:33</pubDate>
        <category><![CDATA[扫盲]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/e893fd2ed1bdee554fc226aa.html</guid>
</item>

<item>
        <title><![CDATA[最近真是顺啊，再添一代码]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/2841a18d95b01c17b21bba74.html]]></link>
        <description><![CDATA[
		
		<p>最近试着写了恶心搜索题之Sudoku，就是数独啦，写了615行，而且包括其拓展</p>
<p>最原始的数独是(3^2)^2的，我参考了一些资料，加了六个剪枝和一个枚举过程，在zju上很轻松过了,然后又到pku上去试了试，把几乎全部名字里带Sudoku的都轻松过了。<img src="http://img.baidu.com/hi/face/i_f01.gif"></p>
<p>然后我进行了Sudoku的拓展，成为了可以计算(n^2)^2的代码，自己试了一下，收获不少。</p>
<p>后来发现zju这个数独题目的数据真是很弱，我有一个回溯上的错误在zoj2580上没有测出来（应该说n=3都测不出来），我用那个n=4的样例数据一测试就发现问题了。我估计按照这些剪枝在zoj上基本只剩下多解的情况，那些回溯大体上都省掉了，而且数值非常小。</p>
<p>1、不是剪枝越多效率越高的，Sudoku就很明显，六个剪枝我去掉了几个时间效率会高一点，但是我估计zju的数据都很弱小，并不是那种很强的数值，我试过我的代码跑法国数独竞赛决赛试题，速度超快，我估计那些剪枝会在比如n比较大的时候显示效果吧！^_^</p>
<p>2、对于n比较小的时候，使用位操作是不错的选择，我的代码里面就用一个整数来代替了bool数组，那个枚举某个格子可能情况的bool数组用一个整数就可以搞定了，而且在清空这个数组时候，对于整数只要赋值为0就可以了，十分的方便。当然，这种做法还是有局限性的，就是整数的位数，这个在n&gt;=6的时候就体现出来了，因为6*6=36&gt;32已经超出32位机子上int范围了，但是对于6以上的模块，估计时间是主要问题。但是总的说来，位操作是强大的。</p>
<p>3、Sudoku的复杂度不仅仅看给定数值的多少，那些难题的划分标准并没有一个严格的说法，据我所知Sudoku也作为了刚刚结束的数模美国赛的题目出现，题目要求就是难度的衡量，那些数值少的并不一定是很难的题目，那些无法确定的情况往往成为了解题的关键点，这时候就需要枚举了，我想这也许是人脑的计算机的区别啊，计算机可以开堆栈记录状态，枚举，而人脑则不擅长这个。我的程序在那些极端情况下（板上没有一个数值）也能瞬间给出解答。</p>
<p>写好代码后就把格式改了一下，对于各种情形弄成通用的方法，那个EMP常量表示的是字符阵中表示空的字符，然后那两个to_char和to_num函数很明显是数值和字符的互换的过程，这样各个题目都通用了。stack是用来暂记状态用来回溯的，sn记录的是剩余个数，然后top表示栈顶，从0开始，can则是标记是否出现矛盾的bool变量。</p>
<p>做完Sudoku有种释然的感觉，但是我看到了有一篇论文中介绍了更好的算法，据说代码200+，而且效率更高，下个阶段就研究一下吧。</p>
<p>代码嘛就小发一下啦！^_^</p>
<p> </p>
<div forimg="1"><img class="blogimg" border="0" small="0" src="http://hiphotos.baidu.com/fzbzchenxi/pic/item/0b7b640011b0b195e950cdfd.jpg"></div>
<p>#include&lt;stdio.h&gt;<br>
#include&lt;memory.h&gt;<br>
#include&lt;algorithm&gt;<br>
const int N=3;<br>
const int N_2=N*N;<br>
const int N_2_2=2*N_2;<br>
const int N_2_3=3*N_2;<br>
const int N_4=N_2*N_2;<br>
const char EMP='0';<br>
struct node<br>
{<br>
int pos[N_2][N_2];<br>
int left[N_2][N_2];<br>
char map[N_2][N_2+1];<br>
int sn;<br>
int x;<br>
int y;<br>
int k;<br>
}stack[N_4];<br>
int ti,i,left[N_2][N_2],pos[N_2][N_2],q[N_4][2],s,e,sn,top;<br>
char map[N_2][N_2+1];<br>
bool can;<br>
inline int to_num(char ch)<br>
{<br>
return ch-'0';<br>
}<br>
inline char to_char(int s)<br>
{<br>
return s+'0';<br>
}<br>
void initial()//初始化<br>
{<br>
int i,j;<br>
sn=N_4;<br>
top=-1;<br>
for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  if (map[i][j]==EMP)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  left[i][j]=N_2;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][j]=((1&lt;&lt;N_2)-1)&lt;&lt;1;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  else<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  left[i][j]=1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][j]=1&lt;&lt;to_num(map[i][j]);<br>
&nbsp;&nbsp;&nbsp;  }<br>
}<br>
void fix(int x,int y)//确定x,y位置的数值<br>
{<br>
int i,j,k,sr,sc;<br>
sn--;<br>
for (i=1;i&lt;=N_2;i++)<br>
&nbsp;&nbsp;  if (pos[x][y]&amp;(1&lt;&lt;i)) break;<br>
map[x][y]=to_char(i);<br>
left[x][y]=pos[x][y]=0;<br>
for (j=0;j&lt;N_2;j++)<br>
{<br>
&nbsp;&nbsp;  if (pos[j][y]&amp;(1&lt;&lt;i))<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  pos[j][y]-=(1&lt;&lt;i);<br>
&nbsp;&nbsp;&nbsp;  left[j][y]--;<br>
&nbsp;&nbsp;&nbsp;  if (left[j][y]==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  e++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  q[e][0]=j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  q[e][1]=y;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
}<br>
for (j=0;j&lt;N_2;j++)<br>
{<br>
&nbsp;&nbsp;  if (pos[x][j]&amp;(1&lt;&lt;i))<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  pos[x][j]-=(1&lt;&lt;i);<br>
&nbsp;&nbsp;&nbsp;  left[x][j]--;<br>
&nbsp;&nbsp;&nbsp;  if (left[x][j]==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  e++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  q[e][0]=x;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  q[e][1]=j;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
}<br>
sr=x/N*N;sc=y/N*N;<br>
for (j=0;j&lt;N;j++)<br>
&nbsp;&nbsp;  for (k=0;k&lt;N;k++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  if (pos[sr+j][sc+k]&amp;(1&lt;&lt;i))<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  pos[sr+j][sc+k]-=(1&lt;&lt;i);<br>
&nbsp;&nbsp;&nbsp;&nbsp;  left[sr+j][sc+k]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (left[sr+j][sc+k]==1)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  e++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  q[e][0]=sr+j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  q[e][1]=sc+k;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
}<br>
bool check_unit()//以队列形式确定可以填上的数值<br>
{<br>
int i,j;<br>
s=0;e=-1;<br>
for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  if (left[i][j]==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  e++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  q[e][0]=i;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  q[e][1]=j;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  else<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (left[i][j]==0&amp;&amp;map[i][j]==EMP)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  can=false;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return false;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
while (s&lt;=e)<br>
{<br>
&nbsp;&nbsp;  if (!left[q[s][0]][q[s][1]])<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  can=false;<br>
&nbsp;&nbsp;&nbsp;  return false;<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  fix(q[s][0],q[s][1]);<br>
&nbsp;&nbsp;  s++;<br>
}<br>
return sn==0;<br>
}<br>
bool check_block()//检测块中只存在单一可能位置的数值<br>
{<br>
bool ret=false;<br>
int i,j,k,m,n;<br>
for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;  for (j=1;j&lt;=N_2;j++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  m=0;<br>
&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][k]&amp;(1&lt;&lt;j))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  m++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m==1) n=k;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (m==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  left[i][n]=1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][n]=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;  for (j=1;j&lt;=N_2;j++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  m=0;<br>
&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[k][i]&amp;(1&lt;&lt;j))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  m++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m==1) n=k;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (m==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  left[n][i]=1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  pos[n][i]=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;  for (j=1;j&lt;=N_2;j++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  m=0;<br>
&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i/N*N+k/N][i%N*N+k%N]&amp;(1&lt;&lt;j))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  m++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m==1) n=k;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (m==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  left[i/N*N+n/N][i%N*N+n%N]=1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  pos[i/N*N+n/N][i%N*N+n%N]=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
return ret;<br>
}<br>
bool check_area()//可能值位于同一块的同一区时，清除可能值在可影响的其他区的作用<br>
{<br>
bool ret=false,area[N&lt;&lt;1];<br>
int i,j,k,l,m,mt,n,nt;<br>
for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;  for (j=1;j&lt;=N_2;j++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  memset(area,false,sizeof(area));<br>
&nbsp;&nbsp;&nbsp;  m=0;<br>
&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if ((pos[i][k]&amp;(1&lt;&lt;j))&amp;&amp;!area[k/N])<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  area[k/N]=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  m++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m==1) n=k/N*N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (m==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  m=i/N*N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (k+m!=i)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[k+m][n+l]&amp;(1&lt;&lt;j))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[k+m][n+l]-=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[k+m][n+l]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
for (i=N_2;i&lt;N_2_2;i++)<br>
&nbsp;&nbsp;  for (j=1;j&lt;=N_2;j++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  memset(area,false,sizeof(area));<br>
&nbsp;&nbsp;&nbsp;  m=0;<br>
&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if ((pos[k][i-N_2]&amp;(1&lt;&lt;j))&amp;&amp;!area[k/N])<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  area[k/N]=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  m++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m==1) n=k/N*N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (m==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  m=(i-N_2)/N*N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (k+m!=i-N_2)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[n+l][k+m]&amp;(1&lt;&lt;j))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[n+l][k+m]-=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[n+l][k+m]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
for (i=N_2_2;i&lt;N_2_3;i++)<br>
&nbsp;&nbsp;  for (j=1;j&lt;=N_2;j++)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  memset(area,false,sizeof(area));<br>
&nbsp;&nbsp;&nbsp;  m=mt=0;<br>
&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[(i-N_2_2)/N*N+k/N][(i-N_2_2)%N*N+k%N]&amp;(1&lt;&lt;j))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m!=2&amp;&amp;!area[k/N])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  area[k/N]=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  m++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  n=k/N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (mt!=N&amp;&amp;!area[k%N+N])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  area[k%N+N]=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  mt++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  nt=k%N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (m==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  m=(i-N_2_2)%N*N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (k/N!=n&amp;&amp;(pos[(i-N_2_2)/N*N+k/N][m+k%N]&amp;(1&lt;&lt;j)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[(i-N_2_2)/N*N+k/N][m+k%N]-=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[(i-N_2_2)/N*N+k/N][m+k%N]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (mt==1)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  mt=(i-N_2_2)/N*N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (k%N!=nt&amp;&amp;(pos[mt+k/N][(i-N_2_2)%N*N+k%N]&amp;(1&lt;&lt;j)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[mt+k/N][(i-N_2_2)%N*N+k%N]-=(1&lt;&lt;j);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[mt+k/N][(i-N_2_2)%N*N+k%N]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  }<br>
return ret;<br>
}<br>
bool check_unit_pair()//两个格的合集为两个元素，则这两个格占有这两个元素<br>
{<br>
bool ret=false;<br>
int i,j,k,l,st[N_2+1][3];<br>
for (i=0;i&lt;N_2;i++)<br>
{<br>
&nbsp;&nbsp;  st[0][0]=0;<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  if (left[i][j]==2)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  st[++st[0][0]][0]=j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  l=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][j]&amp;(1&lt;&lt;k)) st[st[0][0]][++l]=k;<br>
&nbsp;&nbsp;&nbsp;  } <br>
&nbsp;&nbsp;  for (j=1;j&lt;st[0][0];j++)<br>
&nbsp;&nbsp;&nbsp;  for (k=j+1;k&lt;=st[0][0];k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (st[j][1]==st[k][1]&amp;&amp;st[j][2]==st[k][2])<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N_2;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (l!=st[j][0]&amp;&amp;l!=st[k][0])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][l]&amp;(1&lt;&lt;st[j][1]))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][l]-=(1&lt;&lt;st[j][1]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[i][l]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][l]&amp;(1&lt;&lt;st[j][2]))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][l]-=(1&lt;&lt;st[j][2]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[i][l]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
for (j=N_2;j&lt;N_2_2;j++)<br>
{<br>
&nbsp;&nbsp;  st[0][0]=0;<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  if (left[i][j-N_2]==2)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  st[++st[0][0]][0]=i;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  l=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][j-N_2]&amp;(1&lt;&lt;k)) st[st[0][0]][++l]=k;<br>
&nbsp;&nbsp;&nbsp;  } <br>
&nbsp;&nbsp;  for (i=1;i&lt;st[0][0];i++)<br>
&nbsp;&nbsp;&nbsp;  for (k=i+1;k&lt;=st[0][0];k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (st[i][1]==st[k][1]&amp;&amp;st[i][2]==st[k][2])<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N_2;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (l!=st[i][0]&amp;&amp;l!=st[k][0])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[l][j-N_2]&amp;(1&lt;&lt;st[i][1]))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[l][j-N_2]-=(1&lt;&lt;st[i][1]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[l][j-N_2]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[l][j-N_2]&amp;(1&lt;&lt;st[i][2]))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[l][j-N_2]-=(1&lt;&lt;st[i][2]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[l][j-N_2]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
for (i=N_2_2;i&lt;N_2_3;i++)<br>
{<br>
&nbsp;&nbsp;  st[0][0]=0;<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  if (left[(i-N_2_2)/N*N+j/N][(i-N_2_2)%N*N+j%N]==2)<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  st[++st[0][0]][0]=j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  l=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[(i-N_2_2)/N*N+j/N][(i-N_2_2)%N*N+j%N]&amp;(1&lt;&lt;k)) st[st[0][0]][++l]=k;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  for (j=1;j&lt;st[0][0];j++)<br>
&nbsp;&nbsp;&nbsp;  for (k=j+1;k&lt;=st[0][0];k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (st[j][1]==st[k][1]&amp;&amp;st[j][2]==st[k][2])<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N_2;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (l!=st[j][0]&amp;&amp;l!=st[k][0])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[(i-N_2_2)/N*N+l/N][(i-N_2_2)%N*N+l%N]&amp;(1&lt;&lt;st[j][1]))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[(i-N_2_2)/N*N+l/N][(i-N_2_2)%N*N+l%N]-=(1&lt;&lt;st[j][1]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[(i-N_2_2)/N*N+l/N][(i-N_2_2)%N*N+l%N]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[(i-N_2_2)/N*N+l/N][(i-N_2_2)%N*N+l%N]&amp;(1&lt;&lt;st[j][2]))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[(i-N_2_2)/N*N+l/N][(i-N_2_2)%N*N+l%N]-=(1&lt;&lt;st[j][2]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[(i-N_2_2)/N*N+l/N][(i-N_2_2)%N*N+l%N]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
return ret;<br>
}<br>
bool check_num_group()//一个块中n个数值恰好出现在n个格子里，则删除这n个格子里的其他可能<br>
{<br>
bool ret=false;<br>
int i,j,k,st[N_2+1];//记录状态的数组，低5位表示数值k，中间N_2位表示块中的格集合，5位高表示格的个数<br>
for (i=0;i&lt;N_2;i++)<br>
{<br>
&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++) st[k]=k;<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][j]&amp;(1&lt;&lt;k))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[k]|=(1&lt;&lt;(j+5));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[k]+=(1&lt;&lt;(N_2+5));<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  std::sort(st+1,st+N_2+1);<br>
&nbsp;&nbsp;  for (j=1;j+(st[j]&gt;&gt;(N_2+5))&lt;=N_2+1;j++)<br>
&nbsp;&nbsp;&nbsp;  if ((st[j]&gt;&gt;5)==(st[j+(st[j]&gt;&gt;(N_2+5))]&gt;&gt;5))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[j]&amp;(1&lt;&lt;(k+5)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (left[i][k]!=(st[j]&gt;&gt;(N_2+5))) ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][k]=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (left[i][k]=0;left[i][k]&lt;(st[j]&gt;&gt;(N_2+5));left[i][k]++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[i][k]+=(1&lt;&lt;(st[j+left[i][k]]&amp;31));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
for (j=N_2;j&lt;N_2_2;j++)<br>
{<br>
&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++) st[k]=k;<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][j-N_2]&amp;(1&lt;&lt;k))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[k]|=(1&lt;&lt;(i+5));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[k]+=(1&lt;&lt;(N_2+5));<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  std::sort(st+1,st+N_2+1);<br>
&nbsp;&nbsp;  for (i=1;i+(st[i]&gt;&gt;(N_2+5))&lt;=N_2+1;i++)<br>
&nbsp;&nbsp;&nbsp;  if ((st[i]&gt;&gt;5)==(st[i+(st[i]&gt;&gt;(N_2+5))]&gt;&gt;5))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[i]&amp;(1&lt;&lt;(k+5)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (left[k][j-N_2]!=(st[i]&gt;&gt;(N_2+5))) ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[k][j-N_2]=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (left[k][j-N_2]=0;left[k][j-N_2]&lt;(st[i]&gt;&gt;(N_2+5));left[k][j-N_2]++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[k][j-N_2]+=(1&lt;&lt;(st[i+left[k][j-N_2]]&amp;31));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
for (i=N_2_2;i&lt;N_2_3;i++)<br>
{<br>
&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++) st[k]=k;<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[(i-N_2_2)/N*N+j/N][(i-N_2_2)%N*N+j%N]&amp;(1&lt;&lt;k))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[k]|=(1&lt;&lt;(j+5));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[k]+=(1&lt;&lt;(N_2+5));<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  std::sort(st+1,st+N_2+1);<br>
&nbsp;&nbsp;  for (j=1;j+(st[j]&gt;&gt;(N_2+5))&lt;=N_2+1;j++)<br>
&nbsp;&nbsp;&nbsp;  if ((st[j]&gt;&gt;5)==(st[j+(st[j]&gt;&gt;(N_2+5))]&gt;&gt;5))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[j]&amp;(1&lt;&lt;(k+5)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int x=(i-N_2_2)/N*N+k/N,y=(i-N_2_2)%N*N+k%N;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (left[x][y]!=(st[j]&gt;&gt;(N_2+5))) ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[x][y]=0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (left[x][y]=0;left[x][y]&lt;(st[j]&gt;&gt;(N_2+5));left[x][y]++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[x][y]+=(1&lt;&lt;(st[j+left[x][y]]&amp;31));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
return ret;<br>
}<br>
bool check_line_pair()//两行（列）中有一数值只出现在某两列（行）中，删除这两列（行）其他这个数值的出现<br>
{<br>
bool ret=false;<br>
int i,j,k,l,m,st[N_2][N_2+1];<br>
for (i=0;i&lt;N_2;i++)<br>
{<br>
&nbsp;&nbsp;  memset(st[i],0,sizeof(st[i]));<br>
&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][j]&amp;(1&lt;&lt;k))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[i][k]|=1&lt;&lt;j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[i][k]+=(1&lt;&lt;N_2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2-1;i++)<br>
&nbsp;&nbsp;&nbsp;  if ((st[i][k]&gt;&gt;N_2)==2)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (j=i+1;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[j][k]==st[i][k])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N_2;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[i][k]&amp;(1&lt;&lt;l))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (m=0;m&lt;N_2;m++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m!=i&amp;&amp;m!=j&amp;&amp;(pos[m][l]&amp;(1&lt;&lt;k)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[m][l]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[m][l]-=(1&lt;&lt;k);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
for (j=0;j&lt;N_2;j++)<br>
{<br>
&nbsp;&nbsp;  memset(st[j],0,sizeof(st[j]));<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (pos[i][j]&amp;(1&lt;&lt;k))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[j][k]|=1&lt;&lt;i;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  st[j][k]+=(1&lt;&lt;N_2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
for (k=1;k&lt;=N_2;k++)<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2-1;i++)<br>
&nbsp;&nbsp;&nbsp;  if ((st[i][k]&gt;&gt;N_2)==2)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  for (j=i+1;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[j][k]==st[i][k])<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (l=0;l&lt;N_2;l++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (st[i][k]&amp;(1&lt;&lt;l))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (m=0;m&lt;N_2;m++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (m!=i&amp;&amp;m!=j&amp;&amp;(pos[l][m]&amp;(1&lt;&lt;k)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ret=true;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  left[l][m]--;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  pos[l][m]-=(1&lt;&lt;k);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
return ret;<br>
}<br>
void assume()//假设枚举过程<br>
{<br>
int i,j,k,cnt[N_2][N_2];<br>
if (!can)<br>
{<br>
&nbsp;&nbsp;  can=true;<br>
&nbsp;&nbsp;  while (true)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  for (stack[top].k++;stack[top].k&lt;=N_2&amp;&amp;!(stack[top].pos[stack[top].x][stack[top].y]&amp;(1&lt;&lt;stack[top].k));stack[top].k++);<br>
&nbsp;&nbsp;&nbsp;  if (stack[top].k!=N_2+1) break;<br>
&nbsp;&nbsp;&nbsp;  top--;<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  memcpy(left,stack[top].left,sizeof(left));<br>
&nbsp;&nbsp;  memcpy(map,stack[top].map,sizeof(map));<br>
&nbsp;&nbsp;  memcpy(pos,stack[top].pos,sizeof(pos));<br>
&nbsp;&nbsp;  sn=stack[top].sn;<br>
&nbsp;&nbsp;  left[stack[top].x][stack[top].y]=1;<br>
&nbsp;&nbsp;  pos[stack[top].x][stack[top].y]=(1&lt;&lt;stack[top].k);<br>
} <br>
else<br>
{<br>
&nbsp;&nbsp;  top++;<br>
&nbsp;&nbsp;  memset(cnt,0,sizeof(cnt));<br>
&nbsp;&nbsp;  memcpy(stack[top].left,left,sizeof(left));<br>
&nbsp;&nbsp;  memcpy(stack[top].pos,pos,sizeof(pos));<br>
&nbsp;&nbsp;  memcpy(stack[top].map,map,sizeof(map));<br>
&nbsp;&nbsp;  stack[top].sn=sn;<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (map[i][j]==EMP)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (k=0;k&lt;N_2;k++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  cnt[i][k]++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  cnt[k][j]++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  cnt[i/N*N+k/N][i%N*N+k%N]++;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  cnt[i][j]-=3;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  stack[top].x=stack[top].y=-1;<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  for (j=0;j&lt;N_2;j++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;  if (map[i][j]==EMP&amp;&amp;(stack[top].x==-1||left[i][j]&lt;left[stack[top].x][stack[top].y]||<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  (left[stack[top].x][stack[top].y]==left[i][j]&amp;&amp;cnt[i][j]&gt;cnt[stack[top].x][stack[top].y])))<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  stack[top].x=i;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  stack[top].y=j;<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  for (stack[top].k=1;!(stack[top].pos[stack[top].x][stack[top].y]&amp;(1&lt;&lt;stack[top].k));stack[top].k++);<br>
&nbsp;&nbsp;  pos[stack[top].x][stack[top].y]=(1&lt;&lt;stack[top].k);<br>
&nbsp;&nbsp;  left[stack[top].x][stack[top].y]=1;<br>
}<br>
}<br>
void Sudoku()<br>
{<br>
initial();<br>
can=true;<br>
while (true)<br>
{<br>
&nbsp;&nbsp;  if (check_unit()) return;<br>
&nbsp;&nbsp;  if (!can)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  assume();<br>
&nbsp;&nbsp;&nbsp;  continue;<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  if (check_block()) continue;<br>
&nbsp;&nbsp;  if (check_area()) continue;<br>
&nbsp;&nbsp;  if (check_unit_pair()) continue;<br>
&nbsp;&nbsp;  if (check_num_group()) continue;<br>
&nbsp;&nbsp;  if (check_line_pair()) continue;<br>
&nbsp;&nbsp;  assume();<br>
}<br>
}<br>
int main()<br>
{<br>
scanf(&quot;%d&quot;,&amp;ti);<br>
while (ti--)<br>
{<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  scanf(&quot;%s&quot;,map[i]);<br>
&nbsp;&nbsp;  Sudoku();<br>
&nbsp;&nbsp;  for (i=0;i&lt;N_2;i++)<br>
&nbsp;&nbsp;&nbsp;  printf(&quot;%s\n&quot;,map[i]);<br>
}<br>
return 0;<br>
}</p>
<p> </p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/2841a18d95b01c17b21bba74.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%CB%E3%B7%A8">算法</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/2841a18d95b01c17b21bba74.html#comment">查看评论</a>]]></description>
        <pubDate>2008-04-23  13:31</pubDate>
        <category><![CDATA[算法]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/2841a18d95b01c17b21bba74.html</guid>
</item>

<item>
        <title><![CDATA[啥都不说了，发日志纪念一下]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/2841a18deca92517b21bba43.html]]></link>
        <description><![CDATA[
		
		<p>我的zoj已经600AC了，难得啊难得，以前进度快，现在明显慢下来了，做了这么多，庆祝一下，鼓励一下自己，接下去的目标是挤入前十,先给自己打气，好好努力吧！^_^</p>
<p>为表示纪念，把题号发出来吧，哈哈哈哈哈哈哈！！！！！~~~~~</p>
<p>1001 1002 1003 1004 1005 1006 1007 1008 1010 1016 1025 1027 1028 1029 1032 1037 1041 1042 1045 1047 1048 1049 1051 1056 1057 1058 1061 1067 1068 1070 1073 1074 1076 1078 1081 1082 1086 1088 1089 1090 1091 1093 1094 1095 1098 1099 1100 1101 1107 1108 1109 1110 1113 1115 1128 1133 1134 1136 1137 1139 1140 1146 1149 1151 1152 1154 1159 1160 1161 1163 1167 1168 1170 1171 1178 1180 1181 1184 1188 1195 1196 1197 1199 1201 1202 1203 1204 1205 1206 1216 1217 1218 1221 1222 1225 1229 1234 1238 1239 1240 1241 1242 1243 1244 1245 1247 1249 1250 1251 1259 1268 1269 1272 1275 1276 1278 1280 1284 1292 1293 1294 1295 1300 1307 1312 1314 1325 1326 1331 1334 1337 1338 1339 1342 1350 1352 1353 1354 1360 1362 1364 1365 1366 1372 1374 1382 1383 1387 1392 1394 1400 1402 1403 1405 1406 1408 1409 1410 1411 1414 1423 1425 1428 1431 1438 1439 1449 1453 1454 1456 1457 1459 1463 1464 1475 1476 1482 1483 1484 1487 1489 1494 1495 1496 1500 1501 1503 1504 1505 1507 1508 1514 1516 1520 1524 1525 1526 1530 1536 1537 1538 1539 1542 1543 1558 1563 1569 1574 1577 1579 1582 1583 1586 1589 1596 1597 1601 1602 1608 1610 1619 1622 1623 1628 1629 1631 1633 1635 1636 1638 1642 1648 1649 1652 1654 1655 1657 1659 1666 1667 1671 1675 1679 1681 1689 1694 1697 1698 1700 1705 1707 1708 1709 1710 1711 1712 1713 1715 1716 1717 1718 1720 1721 1729 1730 1731 1733 1737 1738 1741 1743 1745 1752 1755 1756 1760 1763 1764 1766 1769 1776 1787 1788 1789 1792 1796 1797 1798 1799 1800 1808 1813 1814 1823 1824 1825 1828 1831 1850 1854 1858 1862 1863 1871 1872 1874 1879 1880 1882 1883 1884 1889 1890 1893 1899 1900 1901 1902 1904 1905 1906 1908 1909 1910 1913 1914 1915 1921 1923 1926 1928 1929 1937 1938 1939 1940 1942 1944 1948 1949 1950 1951 1952 1953 1954 1962 1963 1969 1970 1973 1975 1976 1978 1985 1986 1995 2000 2001 2002 2006 2014 2015 2022 2029 2042 2059 2060 2061 2067 2091 2095 2098 2099 2100 2102 2104 2105 2107 2108 2109 2110 2122 2124 2130 2132 2133 2134 2136 2138 2140 2150 2158 2164 2165 2172 2173 2176 2177 2180 2185 2186 2187 2189 2191 2192 2193 2195 2197 2201 2202 2208 2212 2229 2239 2256 2273 2277 2283 2284 2286 2301 2305 2311 2313 2315 2316 2321 2326 2329 2330 2339 2345 2351 2358 2370 2371 2374 2376 2383 2386 2388 2392 2393 2397 2400 2401 2402 2403 2404 2405 2411 2412 2414 2416 2417 2418 2420 2421 2423 2424 2425 2432 2433 2437 2451 2456 2460 2475 2476 2478 2480 2481 2482 2483 2486 2488 2492 2495 2500 2501 2505 2507 2510 2511 2514 2520 2521 2524 2527 2529 2531 2540 2545 2547 2548 2552 2557 2559 2562 2571 2584 2585 2592 2613 2615 2619 2625 2635 2645 2646 2656 2658 2670 2679 2680 2704 2711 2722 2723 2724 2726 2727 2729 2730 2734 2736 2737 2740 2741 2743 2744 2747 2748 2750 2759 2766 2770 2771 2772 2773 2774 2775 2777 2781 2782 2795 2803 2806 2807 2811 2812 2813 2814 2816 2818 2822 2828 2829 2830 2831 2832 2833 2835 2836 2839 2840 2850 2851 2855 2857 2859 2861 2868 2872 2873 2892 2893 2895 2900 2901 2912 2914 2918 2922 2923 2925 2928 2929 2932 2934 2936 2938 2939 2947 2949 2951 2952 2953 2954 2955</p>
<p> </p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/2841a18deca92517b21bba43.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/2841a18deca92517b21bba43.html#comment">查看评论</a>]]></description>
        <pubDate>2008-04-19  19:50</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/2841a18deca92517b21bba43.html</guid>
</item>

<item>
        <title><![CDATA[《算法导论》课程的题目分析——判定是否存在两数字和为x(P37 2.3-7) 之三]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/a17cb509fd0c94cb3bc7631d.html]]></link>
        <description><![CDATA[
		
		<p><strong>算法分析：</strong>第三种算法的复杂度也是O(nlogn)(其实是他规定的，没办法^_^)，算法的具体思想有点类似，先将这个数组排序，然后利用二分查找来解决（不如第一种算法），枚举每个数组元素，然后查找是否存在一个有序数组中的数和他的和为x（不是本身），二分查找有序数组的时间复杂度为O(nlogn)，乘以枚举的基数n，算法复杂度就是O(nlogn)，加上排序的时间复杂度O(nlogn)，总的分析下时间复杂度还是O(nlogn)（我好废话）。</p>
<p><strong>代码实现：</strong></p>
<p>#include&lt;stdio.h&gt;<br>
#include&lt;algorithm&gt;<br>
const int MAXN=5000;<br>
int i,f,t,mid,n,x,a[MAXN];<br>
int main()<br>
{<br>
scanf(&quot;%d&quot;,&amp;n);<br>
scanf(&quot;%d&quot;,&amp;x);<br>
for (i=0;i&lt;n;i++)<br>
&nbsp;&nbsp;  scanf(&quot;%d&quot;,&amp;a[i]);<br>
std::sort(a,a+n);//再次偷懒用算法库了^_^<br>
for (i=0;i&lt;n;i++)<br>
{<br>
&nbsp;&nbsp;  f=0;<br>
&nbsp;&nbsp;  t=n-1;<br>
&nbsp;&nbsp;  mid=(f+t)&gt;&gt;1;<br>
&nbsp;&nbsp;  while (f&lt;t)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  if (a[mid]+a[i]==x) break;<br>
&nbsp;&nbsp;&nbsp;  else if (a[mid]+a[i]&lt;x) f=mid+1;<br>
&nbsp;&nbsp;&nbsp;  else t=mid-1;<br>
&nbsp;&nbsp;&nbsp;  mid=(f+t)&gt;&gt;1;<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  if (f&gt;=t) continue;<br>
&nbsp;&nbsp;  if (mid!=i||(mid&amp;&amp;a[mid-1]+a[i]==x)||(mid!=n&amp;&amp;a[mid+1]+a[i]==x))<br>
&nbsp;&nbsp;&nbsp;  break;<br>
}<br>
if (i!=n) printf(&quot;%d %d\n&quot;,a[i],x-a[i]);<br>
else printf(&quot;No Answer!\n&quot;);<br>
return 0;<br>
}</p>
<p><strong>测试数据：</strong>同算法一</p>
<p><strong>说明：</strong>不支持用这个算法，只是为了知识的完整性才列出，因为首先他的时间复杂度虽然也是O(nlogn)，但是很容易想到不如算法一快，而且二分查找写代码容易发生错误，这点应该很多人知道（详细可以看看《算法珠玑》介绍的不错），总的来说，从个人感情上来讲，强烈支持第一种算法。<img src="http://img.baidu.com/hi/face/i_f01.gif"><img src="http://img.baidu.com/hi/face/i_f05.gif"></p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/a17cb509fd0c94cb3bc7631d.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%CB%E3%B7%A8">算法</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/a17cb509fd0c94cb3bc7631d.html#comment">查看评论</a>]]></description>
        <pubDate>2008-03-27  20:07</pubDate>
        <category><![CDATA[算法]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/a17cb509fd0c94cb3bc7631d.html</guid>
</item>

<item>
        <title><![CDATA[《算法导论》课程的题目分析——判定是否存在两数字和为x(P37 2.3-7) 之二]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/924abc068bb3ee7f0208810b.html]]></link>
        <description><![CDATA[
		
		<p><strong>算法分析：</strong>这个第二个算法是通过归并排序的原理来实现的，首先我们把数组二分成两个部分，我们采用递归判定左右两个部分内部是否有和为x的元素，如果有直接输出就可以了，否则的话我们考虑这样的情况：一个元素在左边，一个元素在右边，他们的和为x！此时就类似一算法的方法了，因为归并他是建立在前面已经操作的计算：分别对左右两个部分排好序，然后进行合并！这样我们类似一算法设置两个指针，一个指向左边的开始，一个指向右边的结尾，我们开始同样的过程：判断两个指针的指点的和，等于x的话表明已经找到了要求，退出；否则如果大于x表示右边数值太大，右指针向左移动；如果小于x表示左边数值太小，左指针向右移动，这样子就能一直执行这样的过程。</p>
<p><strong>复杂度分析：</strong>由于执行的归并排序的过程，而且检索的时间复杂度和Merge的过程是一样的，因此综合分析来他的情况和归并排序是一样的！即时间复杂度为O(nlogn)，附加空间复杂度为O(n)。</p>
<p><strong>实现代码：</strong></p>
<p>#include&lt;stdio.h&gt;<br>
#include&lt;memory.h&gt;<br>
const int MAXN=5000;<br>
int n,x,y,i,j,a[MAXN],b[MAXN];<br>
bool MergeSort(int f,int t)<br>
{<br>
if (f&gt;=t) return false;<br>
int mid=(f+t)&gt;&gt;1,i,j,l;<br>
if (MergeSort(f,mid)||MergeSort(mid+1,t)) return true;<br>
for (i=f,j=t;i&lt;=mid&amp;&amp;j&gt;mid;)<br>
&nbsp;&nbsp;  if (a[i]+a[j]==x)<br>
&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;  y=a[i];<br>
&nbsp;&nbsp;&nbsp;  return true;<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  else if (a[i]+a[j]&gt;x) j--;<br>
&nbsp;&nbsp;  else i++;<br>
for (i=f,j=mid+1,l=0;i&lt;=mid&amp;&amp;j&lt;=t;)<br>
&nbsp;&nbsp;  if (a[i]&lt;a[j]) b[l++]=a[i++];<br>
&nbsp;&nbsp;  else b[l++]=a[j++];<br>
while (i&lt;=mid) b[l++]=a[i++];<br>
while (j&lt;=t) b[l++]=a[j++];<br>
memcpy(a+f,b,(t-f+1)*sizeof(a[0]));<br>
return false;<br>
}<br>
int main()<br>
{<br>
scanf(&quot;%d&quot;,&amp;n);<br>
scanf(&quot;%d&quot;,&amp;x);<br>
for (i=0;i&lt;n;i++)<br>
&nbsp;&nbsp;  scanf(&quot;%d&quot;,&amp;a[i]);<br>
if (MergeSort(0,n-1)) printf(&quot;%d %d\n&quot;,y,x-y);<br>
else printf(&quot;No Answer!\n&quot;);<br>
return 0;<br>
}</p>
<p><strong>测试数据：</strong>同算法一中，效果还不错</p>
<p><strong>说明：</strong>这个算法的时间复杂度不错，可是有附加空间，与经过优化的算法一有一定的差距，但是思想很不错<img src="http://img.baidu.com/hi/face/i_f01.gif"><img src="http://img.baidu.com/hi/face/i_f05.gif"></p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/924abc068bb3ee7f0208810b.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%CB%E3%B7%A8">算法</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/924abc068bb3ee7f0208810b.html#comment">查看评论</a>]]></description>
        <pubDate>2008-03-27  19:51</pubDate>
        <category><![CDATA[算法]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/924abc068bb3ee7f0208810b.html</guid>
</item>

<item>
        <title><![CDATA[《算法导论》课程的题目分析——判定是否存在两数字和为x(P37 2.3-7) 之一]]></title>
        <link><![CDATA[http://hi.baidu.com/fzbzchenxi/blog/item/4948e24e081f71ced1c86a2c.html]]></link>
        <description><![CDATA[
		
		<p>今天课程的第二个题目是判定是否存在两数字和为x，这个题目要求将时间复杂度限定为O（nlogn），我自己想到了三个算法，一个个来说吧，先说第一个：</p>
<p><strong>问题描述：</strong>输入n个数，求给定数组中是否存在两个数，他们的和为x</p>
<p><strong>输入数据：</strong>元素个数n，和x，数组a</p>
<p><strong>输出数据：</strong>如果存在两个数则输出那两个数，否则输出&ldquo;No Answer！&rdquo;</p>
<p><strong>算法分析：</strong>对于一般情况下，如果用最原始的方法就是枚举那两个数（两重for循环），当然这个算法的时间复杂度肯定不符合我们的要求，是O(n^2)，这里需要O(nlogn)就要想点方法了。我想到的第一个方法是如果我们给这个数组排好序，那么，我们可以构造一个b数组，其中b[i]=x-a[i]，这样b数组就是逆序的了，这时候我们的任务就是判定a[j]=b[i](i!=j)的存在性了，因为a[j]=b[i]可以转换为a[j]=x-a[i]，即a[i]+a[j]=x为我们所需要的式子。判定两个有序的数组是否具有位置不同的相等元素可以在O(n)的时间那完成，这样加上排序的花费，总的算来总的时间复杂度就是O(nlogn)了，满足我们的需求。至于如何在O(n)的时间那完成相等元素的检索，这个比较简单，首先a是升序的，b是降序的，这样我们可以设置两个标点i和j分别指向a和b的最小元素(i=0,j=n-1)，这样每次判断a[i]和b[j]，如果相等则找到，否则如果a[i]大则j--（让b[j]变大），如果a[i]小则i++(让a[i]变大），这样知道i和j相等还没找到的话就退出，表明没有符合题意的解。这个算法的缺点就是需要O(n)的附加空间复杂度，如果我们进行优化就可以使得算法更加完美，我们可以这样考虑：实际上b的数据可以算是一个冗余数据，即通过a和x的数据可以唯一确定b的数据，此时我们省去那个数组b，就能用类似的方法来解决这个问题了，还是设置标点i和j，看看a[i]+a[j]的值和x比较，相等则退出，大于x则j--(减小a[j])，小于x则i++(增大a[i])。这样就去除了那个附加空间了！^_^</p>
<p><strong>实现代码：</strong></p>
<p>#include&lt;stdio.h&gt;<br>
#include&lt;algorithm&gt;<br>
const int MAXN=5000;<br>
int i,j,n,x,a[MAXN];<br>
int main()<br>
{<br>
scanf(&quot;%d&quot;,&amp;n);<br>
scanf(&quot;%d&quot;,&amp;x);<br>
for (i=0;i&lt;n;i++)<br>
&nbsp;&nbsp;  scanf(&quot;%d&quot;,&amp;a[i]);<br>
std::sort(a,a+n);//我比较懒，为了说明主要问题这里用了算法库里自带的排序^_^<br>
i=0;j=n-1;<br>
while (i&lt;j)<br>
{<br>
&nbsp;&nbsp;  if (a[i]+a[j]==x) break;<br>
&nbsp;&nbsp;  if (a[i]+a[j]&gt;x) j--;<br>
&nbsp;&nbsp;  else i++;<br>
}<br>
if (i!=j) printf(&quot;%d %d\n&quot;,a[i],a[j]);<br>
else printf(&quot;No Answer!\n&quot;);<br>
return 0;<br>
}</p>
<p><strong>输入数据：</strong></p>
<p>12<br>
7<br>
2 6 4 8 4 2 10 11 9 6 8 3</p>
<p><strong>输出数据：</strong></p>
<p>3 4</p>
<p><strong>输入数据：</strong></p>
<p>5</p>
<p>5</p>
<p>2 2 2 2 2</p>
<p><strong>输出数据：</strong></p>
<p>No Answer！</p>
<p><strong>说明：</strong>输入和输出数据只是参考，我还测试了几组随机数据，效果还好！<img src="http://img.baidu.com/hi/face/i_f05.gif"></p> <a href="http://hi.baidu.com/fzbzchenxi/blog/item/4948e24e081f71ced1c86a2c.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/fzbzchenxi/blog/category/%CB%E3%B7%A8">算法</a>&nbsp;<a href="http://hi.baidu.com/fzbzchenxi/blog/item/4948e24e081f71ced1c86a2c.html#comment">查看评论</a>]]></description>
        <pubDate>2008-03-27  18:46</pubDate>
        <category><![CDATA[算法]]></category>
        <author><![CDATA[fzbzchenxi]]></author>
		<guid>http://hi.baidu.com/fzbzchenxi/blog/item/4948e24e081f71ced1c86a2c.html</guid>
</item>


</channel>
</rss>