<?xml version="1.0" encoding="utf-8"?><rss version="2.0">
<channel>
<title><![CDATA[代码的质量]]></title>
<link>http://blog.pfan.cn/swell</link>
<description>编程爱好者博客</description>
<language>zh-cn</language>
			<item>
		<title><![CDATA[PKU2418&nbsp;二叉搜索树]]></title>
		<link>http://blog.pfan.cn/swell/49339.html</link>
		<description><![CDATA[http://acm.pku.edu.cn/JudgeOnline/problem?id=2418
二叉搜索树的典型题....
很久没做ACM了,感觉有一个月那么多了吧.
现在来打这些也感觉生疏咯...
BST用到这题目很合适,也有人说用qsort可以过,应该是题目时间太宽的缘故.
上代码...BST
&nbsp;#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
typedef struct BSTNode
{
	char name[100];
	int times;
	struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
int count;

void BSTInsert(BSTree &amp;t,char str[])
{
	BSTree p,f;
	p = t;
	while(p)
	{
		if(strcmp(str,p -&gt; name) == 0)
		{
			p -&gt; times++;
			return;
		}
		f = p;
		p = (strcmp(str,p -&gt; name) &lt; 0) ? p -&gt; lchild : p -&gt; rchild;
	}
	p = (BSTree) malloc (sizeof(BSTNode));
	p -&gt; lchild = p -&gt; rchild = NULL;
	strcpy(p -&gt; name,str);
	p -&gt; times = 1;
	if(t == NULL) t = p;
	else
	{
		( strcmp(p -&gt; name,f -&gt; name) &lt; 0 ) ? (f -&gt; lchild = p) : (f -&gt; rchild = p); 
	}
}

void InOrderTravel(BSTree &amp;t)
{
	if(t != NULL)
	{
		InOrderTravel(t -&gt; lchild);
		printf("%s %.]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-10-16 16:24:00</pubDate>
		</item>
				<item>
		<title><![CDATA[(原创)用矩阵连乘解决公式推导]]></title>
		<link>http://blog.pfan.cn/swell/45946.html</link>
		<description><![CDATA[前些天做了比赛，学到了矩阵连乘，直到今天才真正弄懂了。
TJU3318&nbsp; Chinese rings，这就是简单的矩阵连乘的应用。
当然，学习这个首先要知道二分求幂。
我构造的矩阵是这样的，矩阵A:
1 &nbsp;2&nbsp; 1
1&nbsp; 0&nbsp; 0
0&nbsp; 0&nbsp; 1
起始矩阵是，矩阵B:
f(2)
f(1)
1
目标矩阵是矩阵C:
f(n+1)
f(n)
1
这样矩阵A*B就可得到矩阵
f(3)
f(2)
1
A*（A*B）又可得到
f(4)
f(3)
1
.
.
.
.
.
我感觉很巧妙，也是今天才刚刚体会的。
这样的话 A*A*A....*A*B就可以得到C，然后就得到我们的答案f(n)
我们可以先把前面n-1个A求出来，这里用到二分求幂的方法。
关于二分求幂，我刚开始也不懂。后来去网上搜了下才知道。
话不多说，上代码。
#include &lt;stdio.h&gt;#include &lt;string.h&gt;#define M 200907
void mulmatrix(__int64 a[][3],__int64 b[][3]){&nbsp;&nbsp;&nbsp; int i,j,k;&nbsp;&nbsp;&nbsp; __int64 c[3][3];&nbsp;&nbsp;&nbsp; memset(c,0,sizeof(c));&nbsp;&nbsp;&nbsp; for(i = 0;i &lt; 3;i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j = 0;j &lt; 3;j++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(k = 0;k &lt; 3;k++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c[i][j] = ( c[i][j] + ( ( a[i][k] * b[k][j] ) % M) ) % M;&nbsp;&nbs]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-08-02 13:40:00</pubDate>
		</item>
				<item>
		<title><![CDATA[转自matrix67&nbsp;&nbsp;十个利用矩阵乘法解决的经典问题]]></title>
		<link>http://blog.pfan.cn/swell/45942.html</link>
		<description><![CDATA[十个利用矩阵乘法解决的经典题目 from Matrix67
2009-07-15 16:48





好像目前还没有这方面题目的总结。这几天连续看到四个问这类题目的人，今天在这里简单写一下。这里我们不介绍其它有关矩阵的知识，只介绍矩阵乘法和相关性质。&nbsp;&nbsp;&nbsp;&nbsp; 不要以为数学中的矩阵也是黑色屏幕上不断变化的绿色字符。在数学中，一个矩阵说穿了就是一个二维数组。一个n行m列的矩阵可以乘以一个m行p列的矩阵，得到的结果是一个n行p列的矩阵，其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和。比如，下面的算式表示一个2行2列的矩阵乘以2行3列的矩阵，其结果是一个2行3列的矩阵。其中，结果的那个4等于2*2+0*1：&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; 下面的算式则是一个1 x 3的矩阵乘以3 x 2的矩阵，得到一个1 x 2的矩阵：&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; 矩阵乘法的两个重要性质：一，矩阵乘法不满足交换律；二，矩阵乘法满足结合律。为什么矩阵乘法不满足交换律呢？废话，交换过来后两个矩阵有可能根本不能相乘。为什么它又满足结合律呢？仔细想想你会发现这也是废话。假设你有三个矩阵A、B、C，那么(AB)C和A(BC)的结果的第i行第j列上的数都等于所有A(ik)*B(kl)*C(lj)的和（枚举所有的k和l）。经典题目1 给定n个点，m个操作，构造O(m+n)的算法输出m个操作后各点的位置。操作有平移、缩放、翻转和旋转&nbsp;&nbsp;&nbsp;&nbsp; 这里的操作是对所有点同时进行的。其中翻转是以坐标轴为对称轴进行翻转（两种情况），旋转则以原点为中心。如果对每个点分别进行模拟，那么m个操作总共耗时O(mn)。利用矩阵乘法可以在O(m)的时间里把所有操作合并为一个矩阵，然后每个点与该矩阵相乘即可直接得出最终该点的位置，总共耗时O(m+n)。假设初始时某个点的坐标为x和y，下面5个矩阵可以分别对其进行平移、旋转、翻转和旋转操作。预先把所有m个操作所对应的矩阵全部乘起来，再乘以(x,y,1)，即可一步得出最终点的位置。&nbsp;]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-08-01 17:13:00</pubDate>
		</item>
				<item>
		<title><![CDATA[01背包与完全背包的心得]]></title>
		<link>http://blog.pfan.cn/swell/45925.html</link>
		<description><![CDATA[用一维写的代码。
01背包:&nbsp;&nbsp; for(j = 1;j &lt;= n;j++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = v;i &lt;= 0;i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f[i] = max(f[i],f[i-c[j]]+d[j]);
&nbsp;
完全背包:&nbsp;&nbsp; for(j = 1;j &lt;= n;j++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = 0;i &lt;= v;i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f[i] = max(f[i],f[i-c[v]]+d[i]);
&nbsp;
&nbsp;
两个背包只差在内循环的顺便。因为如果是正着数的话，f[j][i]的状态就会由f[j][i-c[j]]来推导得。
显然f[j][i-c[j]]是已经进入第j种物品的子结果，这是不符合01背包的，而应该是无限背包的。]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-07-31 21:36:00</pubDate>
		</item>
				<item>
		<title><![CDATA[pku题目分类，以后可以照着来练]]></title>
		<link>http://blog.pfan.cn/swell/45837.html</link>
		<description><![CDATA[主流算法：
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.搜索　//回溯
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.DP（动态规划）　
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.贪心　
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.图论　//Dijkstra、最小生成树、网络流
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.数论　//解模线性方程
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.计算几何　//凸壳、同等安置矩形的并的面积与周长
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.组合数学　//Polya定理
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.模拟　
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9.数据结构　//并查集、堆
&Oslash;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.博弈论　
1、&nbsp;&nbsp;&nbsp; 排序
1423, 1694, 1723, 1727, 1763, 1788, 1828, 1838, 1840, 2201, 2376, 2377, 2380,1318, 1877, 1928, 1971, 1974, 1990, 2001, 2002, 2092, 2379, 
1002（需要字符处理，排序用快排即可） 1007（稳定的排序） 2159（题意较难懂） 223]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-07-30 13:02:00</pubDate>
		</item>
				<item>
		<title><![CDATA[简单的并查集&nbsp;hdu1272]]></title>
		<link>http://blog.pfan.cn/swell/45662.html</link>
		<description><![CDATA[今天去杭电做了两道题，主要是看了杭电并查集的讲义。
感觉他讲得非常棒，纯入门了。
也在今天又学了一个新的知识，并查集，感到很高兴。
HDU1272
题目意思是找到判断是不是连通无环的图。
判断成环的时候，只要判断输入边的两个点。有一个共同的父节点，那么这两个点就成环。
判断连通的时候，只要判断根节点数为1即可。
不多说，简单题，上代码。
上代码。
#include &lt;stdio.h&gt;#include &lt;string.h&gt;int k,flag[100005],bin[100005];int find(int x){&nbsp;&nbsp;&nbsp; if(bin[x] == x)&nbsp; return x;&nbsp;&nbsp;&nbsp; return bin[x] = find(bin[x]);}void merge(int x,int y){&nbsp;&nbsp;&nbsp; int fx,fy;&nbsp;&nbsp;&nbsp; fx = find(x);&nbsp;&nbsp;&nbsp; fy = find(y);&nbsp;&nbsp;&nbsp; if(fx != fy)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bin[fx] = fy;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = 0;}int main(){&nbsp;&nbsp;&nbsp; int i,j,n,m,cnt,p;&nbsp;&nbsp;&nbsp; while(scanf("%d%d",&amp;n,&amp;m) != EOF &amp;&amp; n != -1)&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(n == 0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; puts("Yes");&nbsp;&nbsp;&nbsp;&nb]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-07-27 15:00:00</pubDate>
		</item>
				<item>
		<title><![CDATA[prim算法]]></title>
		<link>http://blog.pfan.cn/swell/45613.html</link>
		<description><![CDATA[昨天做了ZOJ1372，挺开心的，又学了一个算法——最小生成树的prim算法。
其实这个算法跟最短路径算法差不了多少，只是其中改了一点点条件。
这样说吧。比如最短路的起点是1号点，那么数组每次更新的都是到1号点的最短距离。
而最小生成树则是到已选的当前点集的最短距离。
两个都是贪心算法的经典。
学的不多，不过每天都在快乐地进步。
上代码：#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int mat[55][55],used[55],min[55];
int p;

int prim()
{
    int i,j,k,q,ret = 0;
    for(i = 1;i &lt;= p;i++)
        min[i] = 1000000000,used[i] = 0;
    min[1] = 0;
    for(i = 1;i &lt;= p;i++)
    {
        k = -1;
        for(j = 1;j &lt;= p;j++)
            if(!used[j] &amp;&amp; (k == -1 || min[j] &lt; min[k]))
                k = j;
        used[k] = 1;
        ret += min[k];
        for(j = 1;j &lt;= p;j++)
            if(!used[j] &amp;&amp; mat[k][j] &amp;&amp; mat[k][j] &lt; min[j])
                min[j] = mat[k][j];
    }
    return ret;
}

int main()
{
    int i,j,n,r,a,b,c;
    while(scanf("%d%d",&amp;p,&amp;r) != EOF &amp;&amp; p != 0)
    {
        memset(mat,0,sizeof(mat));
        for(i = 0;i &lt; r;i++)]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-07-27 10:24:00</pubDate>
		</item>
				<item>
		<title><![CDATA[今天学了优先队列(最大堆)]]></title>
		<link>http://blog.pfan.cn/swell/45368.html</link>
		<description><![CDATA[昨天去做了浙大的月赛。身为ACM菜鸟中的菜鸟的我，简直是被虐。
一个下午只看了一题。ZOJ3230，想了一下午只能想到M*N算法，还想了N种剪枝。
后来想想真是异想天开了吧。哎，一百万次的循环已经够呛，还想要有10000*100000的循环。
第二天看了一下最大堆的，又想到昨天Nineright所讲的C++中有优先队列的模版。
于是用了一下，对a排了个序，Ac了。
代码如下:
&nbsp;
#include &lt;stdio.h&gt;#include &lt;queue&gt;#include &lt;stdlib.h&gt;#include &lt;algorithm&gt;using namespace std;
struct s{&nbsp;&nbsp;&nbsp; int a;&nbsp;&nbsp;&nbsp; int b;}pr[100005];
int cmp1(struct s a,struct s b){&nbsp;&nbsp;&nbsp; return a.a &lt; b.a;}
int main(){&nbsp;&nbsp;&nbsp; int n,m,i,j,k,p;&nbsp;&nbsp;&nbsp; while(scanf("%d%d%d",&amp;n,&amp;m,&amp;p) != EOF)&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = 0;i &lt; n;i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d%d",&amp;pr[i].a,&amp;pr[i].b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sort(pr,pr+n,cmp1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; priority_queue &lt;int&gt; q;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q.push(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp]]></description>
		<author><![CDATA[acmswell]]></author>
		<pubDate>2009-07-20 10:06:00</pubDate>
		</item>
		</channel>
</rss>