题目:http://wikioi.com/problem/1506/
马上就要比赛了,应当来一些集训才是。集训的话,我觉得熟悉算法就好了。
目前掌握的算法虽然不多,不过就我的准备情况而言,算是不错的了,接下来的时间,我觉得就把这些个经典的算法巩固熟练就好了。
今天拿来开刀的题目,虽然解出来了,但是一组数据超时了。额,目前看来还是没有什么优化的手段了。
不过在优化的过程中,我深刻的体会到判断语句是非常耗时的,944ms的计算,多个判断就多到了1001ms。
开始运行一直不知道是哪里出了问题,后来经过调试发现了问题。
一般调试的话,先在程序中插入输出语句来看比较好。不过也可以直接进入debug模式。然后再在最可能的位置插入断点调试。
两个问题的话,一个是判断成功的结束条件弄错了,另一个是没有记录遍历过的节点,导致死循环。
看来在DFS中,结束条件和遍历节点这两个地方是十分容易出错的呀。
上代码好了。不是最优的,我是按照一般的DFS思路来的。
#include <stdio.h>
#include <stdlib.h>
// 全体都-1,1->0
//1、初始化。
//二维关系矩阵,访问列表记录
int maz[1000*1000];
int vis[1000*1000] = {0};
int row;
struct no
{
int i;
int j;
};
int dfs(struct no start,int tofind)
{
int i;
struct no tmp;
//问题在这里面= =
for(i=0 ; start.j+i < row ; i++)
{
//2、达到目的的终止条件
if(maz[start.i*row+start.j+i] == tofind)
{
return 1;
}
//没有访问过、 而且有联系
//对于环状的联系会成死循环
//3、没有访问过,而且邻接的节点
if( vis[start.i*row + start.j+i] != 1 && maz[start.i*row + start.j+i] != -1)
{
vis[start.i*row + start.j+i] = 1;
tmp.i = start.j+i;
tmp.j = 0;
if (dfs(tmp, tofind) == 1)
{
return 1;
}
}
}
return 0;
}
void init()
{
int n;
scanf("%d%d",&row,&n);
int i,j;
for(i=0 ; i<row ; i++)
{
for(j=0 ; j<row ;j++)
{
maz[i*row+j] = -1;
}
}
while(n--)
{
scanf("%d%d",&i,&j);
maz[(i-1)*row+(j-1)] = j-1;
//printf("%dclear\n",n);
}
}
void clear()
{
int j,k;
for(k=0 ; k<row; k++)
{
for(j=0 ; j<row; j++)
{
vis[k*row+j] = 0;
}
}
}
int main()
{
init();
int i;
struct no st;
int j;
for(i=0 ; i< row ;i++)
{
st.i = i;
st.j = 0;
if(dfs(st,i) == 1)
{
printf("T\n");
}
else printf("F\n");
clear();
}
return 0;
}