您的位置:首页 > 其它

XJOJ 105 扫雷

2011-05-26 03:15 204 查看
 

这题是一个回溯题。http://202.117.21.117/xjoj/problem_html/105.html

前后一共交了3个版本,分别把时间从 1312ms 改到了 16ms。

 

 

ID:TIME:NAME:TASK:LANGUAGE:STATUS:CASE:TIME:MEMORY:
261302011-05-26 00:50:50ysg860607105g++Accepted1016MS320KB
261292011-05-26 00:48:42ysg860607105g++Wrong Answer34MS320KB
261282011-05-26 00:44:07ysg860607105g++Accepted10308MS320KB
261272011-05-26 00:39:15ysg860607105g++Accepted10792MS344KB
其实就是对回溯算法进行剪枝,逐步去掉很多无谓的计算。

第一个版本,即id = 26127

 

#include "stdio.h"

int numbers[10001];
bool bombs[10001];

 

int N=0;
int methods=0;

inline bool preCondition(int step)
{
for(int i=0;i<step-1;i++)
if(numbers[i]!=0)
return false;
return true;
}
inline bool isFinish()
{
for(int i=0;i<N;i++)
if(numbers[i]!=0)
return false;
return true;
}
inline void set(int step)
{
bombs[step] = true;
if(step > 0)
numbers[step-1]--;
numbers[step]--;
if(step < N-1)
numbers[step+1]--;
}
inline void reset(int step)
{
bombs[step] = false;
if(step > 0)
numbers[step-1]++;
numbers[step]++;
if(step < N-1)
numbers[step+1]++;
}
inline void search(int step)
{
if(isFinish())
{
methods++;
#if 0
cout << "Solution No."<< methods <<":" << endl;
for(int i=0;i<N;i++)
cout << bombs[i] <<',';
cout << '/b'<< endl;
#endif
return ;
}
for(int i=step;i<N;i++)
{
if(preCondition(i))
{
set(i);
search(i + 1);
reset(i);
}else
return;
}
}
inline void solve(int num[],int N)
{
for(int i=0;i<N;i++)
bombs[i] = 0;
search(0);
}
int main()
{
scanf("%d",&N);
for(int i=0;i<N;i++)
scanf("%d",&numbers[i]);
solve(numbers,N);
printf("%d",methods);
return 0;
}

接下来,分别对两个条件判断函数进行了优化,去掉了不必要的判断。

 

inline bool preCondition(int step)
{
if(step > 1 && numbers[step-2] !=0)
return false;
return true;
}
inline bool isFinish(int step)
{
int i = 0;
if(step > 2)
i = step - 2;
for(;i<N;i++)
if(numbers[i]!=0)
return false;
return true;
}

 

然后时间就一下子减少到16ms了。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息