ZOJ Problem 1017

Problem: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1017

这是什么题呢。个人觉得,是一道编程题,大概大很久之前想跳过这题。现在也明白原因了,它没有用很花哨的算法,也没有非常复杂的数学定理。但是它难在哪里呢?是的,是实现。在做出这题后,我觉得最难的是实现,而且它的设计还的确需要一些Design Pattern里的东东。

解决这个题的关键是重新建立坐标系,准确无误的标识出 1. 原来的六边形 2. 将要被放进来的三角形 3. 当前是否可以放入某一种类型的三角形 4. 更新当前的状态,在放入某一种三角形之后。

这样来建立坐标系。首先观察图1. 1019.1。 可以看到所有的三角形事实上只有两种,一种头向上,一种头向下。如果我们能用一种新的方式来标识任何一个最小的三角形,我的问题基本就解决了。观察图2, 1019.2。黑的三角形和白色的三角形都可以用这样的方式来标识。比如三角型 (0,0), (1,0), (0,1) 实际上就是四边形(0,0), (1,0),(1,1), (0,1)其中的一半,而另一个三角形(0,1), (1,1), (1,0) 是另一半。而我们可以通过任何一个三角形所在的四边形的左下点再加上一个朝向来表示是哪一个三角形。比如三角形 (3,4) ,(4,3),(4,4)就可以用(3,3, 0)表示,这个坐标表示。它是以(3,3)为顶点, 而且是头向下的那一个三角形来唯一表示。

而在实现的时候,直接将所有向上和向下的三角形放在两个数组里来记录hex[0]和hex[1]分别track头向下和头向上的三角形。参见图 1019.3

有了这种表示。所有的事情就会方便一些。接下来,只要实现一个对N长等边三角形进行拆解过程就可以了。如果判断一个N长的三角形是否可以放进当前的画布,只要看看它的所有子三角形是否已经被占用就可以了。实现中的Iterate就是这个作用。它可以实现一次对给定长度和朝向的三角形的子三角形进行一次遍历。而遍历时做什么,则是灵活的。可以是Seter,把所有的子三角形设置成1 (表示占用)。Cleaner,把所有的子三角形设置成0(表示空数)。以及Checker来检查是否可以所有的子三角形都未被占用。

有了所有的这些,实现就相对容易了。

1. 把所有的可能三角形排序,如果后面的长度是前面的某一个长度的N倍,则去掉。因为它可以用前的三角形表示。另外,如果三边形长度是len,而其中有某一个长度正好可以除尽,则返回YES。

2. 初始化三边形。比如一个长度为len的六边形,可以这样来表示。它可以是正方形(新的坐标系里的正方形) (0,0) 长度是len再减去三角形(0,0, 1, len)和 (len, len, 0, len),其中头两个数表示三角形所在的四边形左下顶点,第三个元素表示三角形头是否朝上(只有0,1), 第四个元素表示这个等边三角形的长度。比如(0,0, 1, len)实际表示三角形(0,0),(0,len),(len,0). 只要把这两个三角形表示成占用做为初始状态。那么实际上就表示了六边形。

3. 递归所有的可能解。这一步还是很关键的。参数很重要,实际上也决定了递归的顺序。我的基本想法是, 一层一层向上排,当前这一层先排向上的三角形,再排向下的三角形。给定一个坐标点,(x,y)以及另一个参数up,来表示当前排向上的三角形还是向下的三角形。如果up=true,那么,我假设所有的小于y的层都已经被放满了,同时,当前这一层中向上的三角形里小于x的也都被放满了。然后向x的正向找下一个空的位置。如果没有了,说明这一层都排满了,接着开始排当前这一层头向下的三角形。如果up=false,也是类似。停卡的条件是所有的层都被排满。直接返回true. 如果所有的可能都没有返回false.

//=========================================================================
// ZOJ Problem No.1017
// Auther:  Jonas, Yang
// Mail  :  jonas.yang.jun@gmail.com
// Data  :  Mar.19.2011
// Performance Status:
// Running time | Memory | Language
// 0.26s		| 188K	 | C++
//=========================================================================

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;

class BTriangle
{
public:
    int len;
    vector<int> subTris;
	vector<vector<int> > hex[2];

	class Functor
	{
	public:
		vector<vector<int> > * hex;
        virtual bool operator()(int x, int y, bool up){ return false;};
	};

	class Checker: public Functor
	{
	public:

		Checker(vector<vector<int> > * _hex) { hex = _hex;};
		bool operator()(int x, int y, bool up)
		{
			return (*(hex + up))[x][y] == 0;
		}
	};

	class Cleaner: public Functor
	{
	public:
		Cleaner(vector<vector<int> > * _hex) { hex = _hex;}
		bool operator()(int x, int y, bool up)
		{
			(*(hex + up))[x][y] = 0;
			return true;
		}
	};

	class Seter: public Functor
	{
	public:
		Seter(vector<vector<int> > * _hex) { hex = _hex;}
		bool operator()(int x, int y, bool up)
		{
			(*(hex + up))[x][y] = 1;
			return true;
		}
	};

    Seter seter;
    Checker checker;
    Cleaner cleaner;

	bool Iterate(int x, int y, int length, bool bUp, Functor & f)
	{
		for ( int i = 0; i < length; ++i ) {
			int xStart = bUp ? x : x + i;
			int yStart = bUp ? y + i : y + length - i - 1;
			for ( int j = 0; j < length - i; ++j ) {
				if ( bUp ) {
					if ( !f(xStart + j, yStart, true) ) {
						return false;
					}
					if ( j < length - i - 1 && !f(xStart + j, yStart, false)) {
						return false;
					}
				} else {
					if ( !f(xStart + j, yStart, false) ) {
						return false;
					}
					if ( j > 0 && !f(xStart + j, yStart, true)) {
						return false;
					}
				}
			}
		}
        return true;
	}
	BTriangle():seter(Seter(hex)), cleaner(Cleaner(hex)), checker(Checker(hex))
	{
		cin >> len;
		int N;
		cin >> N;
		subTris.resize(N);
		for ( int i = 0; i < N; ++i ) {
			cin >> subTris[i];
		}

	}

	bool IsAcceptable(int x, int y, int length, bool bUp )
	{
        if ( x < 0 || y < 0 || x + length > hex[0].size() || y + length > hex[0].size() ) {
            return false;

        }

		return Iterate(x, y, length, bUp, checker);
	}

	bool FillHex(int x, int y, bool bUp)
	{
		if ( y >= hex[1].size() ) {
			return true;
		}

        if ( bUp ) {
            while ( x < hex[1].size()  ) {
                if ( !hex[1][x][y] ) {
                    break;
                }
                x ++;
            }

            if ( x == hex[0].size() ) {
                return FillHex(0, y, false);
            }

            for ( int i = 0; i < subTris.size(); ++i ) {
                if ( IsAcceptable(x, y, subTris[i], true) ) {
                    Iterate(x, y, subTris[i], true, seter );
                    if ( FillHex(x + subTris[i], y, bUp) ) {
                        return true;
                    }
                    Iterate(x, y, subTris[i], true, cleaner );
                }
            }
        } else {
            while( x < hex[0].size() ) {
                if ( !hex[0][x][y] ) {
                    break;
                }
                x ++;
            }

            if ( x == hex[0].size() ) {
                return FillHex(0, y + 1, true);
            }

            for ( int i = 0; i < subTris.size(); ++i ) {
                if ( IsAcceptable(x - subTris[i] + 1, y, subTris[i], false) ) {
                    Iterate(x - subTris[i] + 1, y, subTris[i], false , seter);
                    if (FillHex(x + 1, y, false)) {
                        return true;
                    }
                    Iterate(x - subTris[i] + 1, y, subTris[i], false, cleaner);
                }
            }
        }

        return false;
	}

    bool IsDevided()
    {
        // Refine subTris
        sort(subTris.begin(), subTris.end());

        // Check whether there is dividable side in subTris. If so, return true.
        {
            int i = 0;
            for (; i < subTris.size() && subTris[i] <= len; ++i ) {
                if (!(len % subTris[i])) {
                    return true;
                }
            }

            subTris.erase(subTris.begin() + i, subTris.end());
        }


        vector<int> subRefined;
        for ( int i = 0; i < subTris.size(); ++i ) {
            int j = 0;
            for ( ; j < i; ++j ) {
                if (!(subTris[i] % subTris[j])) {
                    break;
                }
            }

            if ( j == i ) {
                subRefined.push_back(subTris[i]);
            }
        }

        subTris = subRefined;

        {
            hex[0].resize(len * 2 , vector<int>(len * 2, 1));
            hex[1].resize(len * 2, vector<int>(len * 2, 1));

            Iterate(0, 0, len, true , cleaner );

            if ( FillHex(0, 0, true) ) {
                return true;
            }
        }

        {
            hex[0].resize(len * 2 , vector<int>(len * 2, 1));
            hex[1].resize(len * 2, vector<int>(len * 2, 1));

            Iterate(0, 0, len, true , cleaner );
            Iterate(0, 0, len, false , cleaner );

            if ( FillHex(0, 0, true) ) {
                return true;
            }
        }

        {
            hex[0].resize(len * 2 , vector<int>(len * 2, 1));
            hex[1].resize(len * 2, vector<int>(len * 2, 1));

            Iterate(0, 0, len, true , cleaner );
            Iterate(0, 0, len, false , cleaner );
            Iterate(0, len, len, true , cleaner );

            if ( FillHex(0, 0, true) ) {
                return true;
            }
        }

        {
            hex[0].resize(len * 2 , vector<int>(len * 2, 0));
            hex[1].resize(len * 2, vector<int>(len * 2, 0));

            Iterate(0, 0, len, true , seter );
            Iterate(len, len, len, false , seter );

            if ( FillHex(0, 0, true) ) {
                return true;
            }
        }

        return false;
    }
};

int main()
{
    int caseCnt = 0;
    cin >> caseCnt;
    while( caseCnt-- > 0 ) {
        BTriangle bt;
        if (bt.IsDevided()) {
            cout << "YES" << endl;
        } else {
            cout << "NO" << endl;
        }
    }
    return 0;
}

发表在 未分类 | 发表评论

Hello world!

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!

发表在 未分类 | 1条评论

ZOJ Problem 1009

Problem source: http://acm.zju.edu.cn/show_problem.php?pid=1009.

这是一道排列变换的题目. 题目本身不容易理解. 有耐心的就仔细看看题目吧, 如果不把题目理解清楚, 一定会在解的过程中出问题. 我一开始认为题目中的sample有错, 结果我错了…

有人认为题目很easy. 当然, 如果只要求解出来的确不难. 有几点很有意思, 个人也觉得不太合理, 但事实如此, 虽然下面的方法很依赖测试数据, 但工程中我们要解决的问题往往不一定需要很通用, 所以也不一定是完全不可取的方法. 注意main() 函数中的string分配, 完全是硬试出来的, 用不断的submit以及返回的segmentation fault做为判断依据得到的数据.

1. 大多数人的做法是正向模拟排列复合最后的结果. 这样做有一个不好地方, 就是在最后得到复合的结果后, 还需要反向查找. 我用了另一种思路, 从一开始就维护一张反向表, 最后只需要直接用密文的字母做为index,即可得到结果.

2. 许多人把一次输入做为基本单位, 中间有很多重复计算. 可以这样理解, 每一次按扭时, 这时的状态对于所有的第i个字母来说都是一样的. 我的做法是把所有的密文全部输入, 然后维护一张反查表, 这样的好处是测试数据如果一个case的密文有多条, 且都不一样时, 效率是很高的. 当然如果数据量太大时现在的做法也是不合适的, 这是一种用空间换时间的方法.

3. 优化求余操作. 求余会被转化为除法操做, 在算法中的核心函数rotate大量使用求余操作. 考虑用LookUpTable做加速. 时间从0.04s降到了0.02s. 这个哈稀表很简单, 但却有大用处. 另外就是要处理LookUpTable的大小, 越小越好…

4. 关于permutation的一些推导, 有兴趣的自己研究一下吧… 可以用inverse permutation, permutation cycles和multiply permutation做关键字去google一把… 如果想深入看, 需要读Knuth的TACOP, I, section 1.3.3 和 III section 5.1. 可以帮你在无尽的绕圈圈中找到一些方向感… :)

_________________________________________________________

Performance status

Run time Run memory Language
00:00.02 sec 420K C++

___________________________________________________________

#include <stdio.h>
#include <memory.h>

int LookUpTable[26*3];
void inverse( int size, int src[] )
{
    static int tmp[26],i;
    for ( i = 0; i < size ; i++  ) {
        tmp[src[i]] = i;
    }
    memcpy(src,tmp,sizeof(int)*size);
}

void multiply( int size, int src0[], int src1[], int dst[] )
{
    int i;
    for ( i = 0 ; i < size; i++ ) {
        dst[i] = src1[src0[i]];
    }
}

void rotate( int size ,int rotor[], int offset[], int * start)
{
    int idx,i;
    // Rotate r1^{-1}
    start[0] = (start[0] + size – 1) % size;
    idx = start[0];
    for ( i = 0 ; i < size ; i++ ) {
        rotor[i] = LookUpTable[i + offset[idx] + size ];
        idx = LookUpTable[idx + 1];
    }
}

// Denote the rotor0, rotor1, rotor2 as r0, r1, r2.

int main()
{
    int size,i,j,cnt;
    int enigmaCnt = 1;
    int rotor[5][26];
    char string[26][1001];
    int flags[26];
    int listLen;
    int start,cur;
    int curChar;
    int starter[3];
    int offset[3][26];
    bool bChange;
    int counter0,counter1;
    int sizeSquare;
    int *pTable;
    do {
        scanf( "%d\n", &size );
        if ( !size ) {
            break;
        }
        if ( enigmaCnt != 1 ) {
            printf("\n");
        }

        pTable = LookUpTable;
        for ( j = 0 ; j< 3 ; j++ ) {
            gets(string[0]);
            for ( i = 0 ; i < size ; i++ ){
                rotor[j][i] =  string[0][i]-’A';
                offset[j][rotor[j][i]] = i – rotor[j][i];
                // Init lookup table here.
                *pTable++ = i;
            }
            // Let l = r0*r1*r2
            // l^{-1} = r2^{-1}*r1^{-1}*r0^{-1}
            inverse(size,rotor[j]);
        }
        // r3 = r2^{-1}*r1^{-1}
        multiply(size,rotor[2],rotor[1],rotor[3]);

        scanf( "%d\n", &cnt );
        printf( "Enigma %d:\n",enigmaCnt++);
        for ( i = 0; i < cnt – 1; i++ ) {
            // Init input and linked list.
            gets(string[i]);
            flags[i] = i + 1;
        }
        gets(string[i]);
        flags[i] = -1;
        listLen = cnt;

        // Init stage.
        start = curChar = cur = 0;
        bChange = false;
        starter[0] = starter[1] = starter[2] = 0;
        sizeSquare = size*size;
        counter0 = counter1 = 0;

        do{
            int last = cur;
            int thisLen = listLen;
            cur = start;
            // Compute l^{-1} for current stage
            // r2 changed.
            if ( 0 == counter1 && curChar ) {
                bChange = true;
                rotate(size,rotor[2],offset[2],starter + 2);
            }

            // r1 changed.
            if ( 0 == counter0 && curChar  ) {
                bChange = true;
                rotate(size,rotor[1],offset[1],starter + 1);
            }
            if ( bChange ) {
                bChange = false;
                multiply(size,rotor[2],rotor[1],rotor[3]);
            }

            multiply(size,rotor[3],rotor[0],rotor[4]);

            for ( i = 0 ; i < thisLen; i ++ ) {
                // When current string is processed, delete it from list.
                if ( ” == string[cur][curChar] ) {
                    if ( thisLen == 1 ) {
                        listLen –;
                    } else{
                        if ( cur == start ) {
                            start = flags[cur];
                        } else if ( -1 == flags[cur] ) {
                            flags[last] = -1;
                        } else {
                            flags[last] = flags[cur];
                        }
                        listLen–;
                    }
                } else {
                    string[cur][curChar] =
                        ‘a’ + rotor[4][string[cur][curChar]-’A'];
                    last = cur;
                }
                cur = flags[cur];
            }
            // r0 always change.
            rotate(size,rotor[0],offset[0],starter);
            curChar++;
            if( counter0  == size – 1 ){
                counter0 = 0;
            } else{
                counter0++;
            }

            if( counter1  == sizeSquare – 1 ){
                counter1 = 0;
            } else{
                counter1++;
            }

        }while( listLen );

        for ( i = 0; i < cnt; i++ ) {
            printf("%s\n",string[i]);
        }
    } while (1);

    return 0;
}

发表在 未分类 | 发表评论

一部不错的电影

我是一个挺爱看电影, 而且对于"好"电影的标准不高的人…  看了半天GPU GEMS 3中关于通用计算的部分, 今天看了一部电影,  在讲一个人爱上一个星星的故事….
对于我这样的理科书呆子, 在缺少许多imagine 的能力下, 对于这样有样童话故事的电影, 还会觉得很有趣…. 不过我有一个很有文学气质的朋友, 现在看电影, 如果不是特别变态, 特别恶心, 或是特别恐怖的, 他是不会称之为"好"电影了…. 我感觉他是在考验我的心理承受能力, 我觉得受不了的, 他一定说好…. 你说这都是什么人啊…. 把自己的快乐建立在别人的痛苦上….呵呵~~不过说来也怪, 我却很喜欢和他一起看电影…
回到正题, 这是一部英国气息很浓的电影, 传统, 绅士而且又通露着自己我感觉的高贵…  一个美丽的童话故事, 虽然现在的人都不好骗, 但如果能自圆其说, 大家还是会去欣赏一个"人造"的美丽的… 一个平凡的小子最后变成了一个他从来都没有想过成为的国王…  其中很多小细节还是结合的很好, 虽然结局过于完美, 不重要的人物有些死得过于随便, 但是的确情节上设计还是比较合理的… 而且其中一些搞笑的小插曲, 也让有些过于正面的主题得到一些中和… 说得太详细估计你就没有兴趣去看了…是吧?
如果你有另一半, 快带着它去看吧….呵呵~~
发表在 未分类 | 6条评论

若干以前的东东

一直想把自己做过的东东和别人共享一把,最近在以前高中的数学老师的帮助下,找到了共享空间. 看到这篇文章的人里应该也有认识他的人, 他是王新敞老师,很庆幸自己能成为他的一名学生… 现在如果还有在上高中的弟弟妹妹的兄弟们,可以去王老师的主页,那里有大量的高中数学的资料…

http://www.xjktyg.com/wxc

以下是一些共享的资料,以后有空再不段增加一些….:)

  • 研究生毕业论文
    • 是关于三角B样条的绘制的东东,遗憾的是这个项目还没有完全做完,毕业之后就再也没有空多动它了…我把Latex源文件和生成的pdf都放上来了,以后要用Latex写论文的兄弟可以参考一把,里面用了不少Latex的高级功能,有了源文件改改就可以用了….源文件打成了bzip2包,Linux下用"tar -jxvf master-thesis.tar.bz2"就可以了,在Windows下,用winrar就可以解了. 我写的时候用的Tex环境是: Windows: WinEdit + TexLive. 后来在Linux下也生成过,Linux: TexMaker + TexLive. 另一个就是生成的pdf文件了.
    • Download1: [Latex src]
    • Download2: [Pdf]
  • TACOP Answer
    • 凡是CS的人,应该没有不知道 "Donald E. Knuth", 说起Knuth, 应该不知道"The Art of Computer Programming"的. 我听过一个朋友说用了一两个月就快读完第一卷了, 然后我问收获是什么? 回答是"好像没有什么新的东西"… 这里就不点名了…:) 不过如果真是这样草草看过, 还不如动手多做几道算法的题目… 我比较赞成尽量把里面所有的题目都做一下, 当然有些题目太BT, 先做个记号就好了…我看得很慢, 也是有空的时候看一点点, 所以把题目和答案都顺便整理下来了…这是一个长期计划, 希望有一天能真的完成, 不过想想也应该是两三年的事情…
    • Download1: [Latex Src]
    • Download2: [Pdf]
  • Summary of Bezier Curve
    • 这是在CHG Graphics Team时写的一个报告, 关于Bezier曲线的内容… 有兴趣的兄弟们就看看吧…
    • Donwload1: [Pdf]
发表在 未分类 | 5条评论

任务管理器里的正弦波

最近和一个MSRA的友人聊天时,说起了一个BT的问题。这位友人自然是程序设计的大牛,同样出对技术的热情,使我们很有共同语言。

前些时间,他聊起来一个很有意思的问题,我觉得很有意思,于是动手试了一把,原来是可以实现的。不过产生的结果没有到很理想的状态,有兴趣的可以继续动手。。。

题目是: 在Windows 的任务管理器里, 我们可以看到CPU占用率会被以固定的时间间隔采样下来,从而形成一条曲线, 那么在比较理想的情况下, 可以写一个程序让这条曲线变成方波, 或是更复杂的正弦波吗?

BT的问题自然会吸引BT的人…于是我就实现了一把…

发表在 未分类 | 3条评论

ZOJ_1008

Gnome Tetravex

Time limit: 10 Seconds   Memory limit: 32768K  
Total Submit: 4852   Accepted Submit: 991  

Hart is engaged in playing an interesting game, Gnome Tetravex, these days. In the game, at the beginning, the player is given n*n squares. Each square is divided into four triangles marked four numbers (range from 0 to 9). In a square, the triangles are the left triangle, the top triangle, the right triangle and the bottom triangle. For example, Fig. 1 shows the initial state of 2*2 squares.


Fig. 1 The initial state with 2*2 squares

The player is required to move the squares to the termination state. In the termination state, any two adjoining squares should make the adjacent triangle marked with the same number. Fig. 2 shows one of the termination states of the above example.


Fig. 2 One termination state of the above example

It seems the game is not so hard. But indeed, Hart is not accomplished in the game. He can finish the easiest game successfully. When facing with a more complex game, he can find no way out.

One day, when Hart was playing a very complex game, he cried out, "The computer is making a goose of me. It’s impossible to solve it." To such a poor player, the best way to help him is to tell him whether the game could be solved. If he is told the game is unsolvable, he needn’t waste so much time on it.

Input

The input file consists of several game cases. The first line of each game case contains one integer n, 0 <= n <= 5, indicating the size of the game.

The following n*n lines describe the marking number of these triangles. Each line consists of four integers, which in order represent the top triangle, the right triangle, the bottom triangle and the left triangle of one square.

After the last game case, the integer 0 indicates the termination of the input data set.

Output

You should make the decision whether the game case could be solved. For each game case, print the game number, a colon, and a white space, then display your judgment. If the game is solvable, print the string "Possible". Otherwise, please print "Impossible" to indicate that there’s no way to solve the problem.

Print a blank line between each game case.

Note: Any unwanted blank lines or white spaces are unacceptable.

Sample Input

2
5 9 1 4
4 4 5 6
6 8 5 4
0 4 4 3
2
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
0

Output for the Sample Input

Game 1: Possible

Game 2: Impossible


Problem Source: Asia 2001, Shanghai (Mainland China)
 
ANSWER:
My solution is as following. This solution is derived from another solution
 
#include <stdio.h>
int g=0;         /*Game index*/
int n=0;         /*Puzzle size */
int q=0;         /* How many different types of squares */
int square[25][4];   /* Source squares */
int count[25];      /*Quantity of a certain type of squares */
int table[25];      /*Solution */
int n2;
int *pSquare;
	/*
	0 1
	2 3*/

	int Square2X2[4] = {
		0x0, 0x11, 0x28, 0x39
	};

	/*
	0 1 2
	3 4 5
	6 7 8*/

	int Square3X3[9] = {
		0x00, 0x11, 0x38,
		0x49, 0x21, 0x59,
		0x68, 0x79,	0x89
	};

	/*
	0   1   2   3
	4   5   6   7
	8   9   10  11
	12  13  14  15*/

	int Square4X4[16] = {
		0x00, 0x11, 0x48, 0x59,
		0x21, 0x69, 0x31,	0x79,
		0x88, 0x99, 0xA9, 0xB9,
		0xC8, 0xD9, 0xE9, 0xF9
	};

	/*
	0	1	2	3	4
	5	6	7	8	9
	10	11	12	13	14
	15	16	17	18	19
	20	21	22	23	24*/

	int Square5X5[25] = {
		0x00,	0x11,	0x58,	0x69,	0x21,
		0x79,	0x31,	0x89,	0x41,	0x99,
		0xA8,	0xB9,	0xC9,	0xD9,	0xE9,
		0xF8,	0x109,	0x119,	0x129,	0x139,
		0x148,	0x159,	0x169,	0x179,	0x189

	};

int place(int pos)
{
	int i;
	int tpInt32,tpIdx;
	if(pos== n2)
		return 1;
	tpInt32 = pSquare[pos];
	tpIdx = tpInt32 >> 4;
	tpInt32 &= 0xF;
	for(i=0; i<q; i++) {
		if (count[i] == 0) {
			continue;
		}
		if (tpInt32) {
			if ( (tpInt32&0x1) && square[table[tpIdx-1]][1]!=square[i][3] ) {
				continue;
			}
			if ( (tpInt32&0x2) && square[table[tpIdx+n]][0]!=square[i][2]) {
				continue;
			}
			if ( (tpInt32&0x4) && square[table[tpIdx+1]][3]!=square[i][1]) {
				continue;
			}
			if ( (tpInt32&0x8) && square[table[tpIdx-n]][2]!=square[i][0]) {
				continue;
			}
		}

		table[tpIdx]=i; 

		count[i]--; 

		if(place(pos+1)==1)
			return 1; 

		count[i]++;
	} 

	return 0;
} 

int main()
{
	int i, j;
	int t, r, b, l;
	int *SquareTable[4] = {Square2X2,Square3X3,Square4X4,Square5X5};
	g=0;
	q=0; 

	while(1)
	{
		g++; 

		scanf("%d", &n);
        n2 = n*n;

		if(n==0)
			break; 

		q=0; 

		for(i=0; i<n2; i++)
		{
			scanf("%d %d %d %d", &t, &r, &b, &l); 

			j=0; 

			while(j<q)
			{
				if(square[j][0]==t && square[j][1]==r && square[j][2]==b && square[j][3]==l)
				{
					count[j]++;
					break;
				} 

				j++;
			} 

			if(j==q)
			{
				square[j][0]=t;
				square[j][1]=r;
				square[j][2]=b;
				square[j][3]=l; 

				count[j]=1; 

				q++;
			}
		}
		if ( n == 1 ) {
			if(g>1){
			printf("\n");
			}
			printf("Game %d: Possible\n", g);
			continue;
		}
		pSquare = SquareTable[n-2];
		if(g>1)
			printf("\n");
		if(place(0)==1)
			printf("Game %d: Possible\n", g);
		else
			printf("Game %d: Impossible\n", g);
	}
	return 0;
} 

Running Time: 3.09s
Memory: 396K
Another answer from 

/* source:  zju
1008 *//* describe: dfs   *//* status:  6.83s-_- *//* author:  sqc2936  */

#include <stdio.h>

int g=0;         //Game index int n=0;         //Puzzle size int
q=0;         //How many different types of squares int square[25][4];  
//Source squares int count[25];      //Quantity of a certain type of squares
int table[25];      //Solution

int place(int pos) {    int i;

   if(pos==n*n)       return 1;

   for(i=0; i<q; i++)    {       if(count[i]==0)         
continue;

      if(pos%n!=0)          if(square[table[pos-1]][1]!=square[i][3])
            continue;

      if(pos/n!=0)          if(square[table[pos-n]][2]!=square[i][0])
            continue;

      table[pos]=i;

      count[i]--;

      if(place(pos+1)==1)          return 1;

      count[i]++;    }

   return 0; }

int main() {    int i, j;    int t, r, b, l;   //Temporary
variables for input (top, right, bottom, left)

   g=0;    q=0;

   while(1)    {       g++;

      scanf("%d", &n);

      if(n==0)          break;

      q=0;

      for(i=0; i<n*n; i++)       {          scanf("%d %d %d %d",
&t, &r, &b, &l);

         j=0;

         while(j<q)          {             if(square[j][0]==t
&& square[j][1]==r && square[j][2]==b &&
square[j][3]==l)             {                count[j]++;
               break;             }

            j++;          }

         if(j==q)          {             square[j][0]=t;
            square[j][1]=r;             square[j][2]=b;
            square[j][3]=l;

            count[j]=1;

            q++;          }       }

      if(g>1)          printf("\n");       if(place(0)==1)
         printf("Game %d: Possible\n", g);       else         
printf("Game %d: Impossible\n", g);    }

   return 0; }

Running Time: 6.83s

Memory: 396K

发表在 未分类 | 1条评论