OJ常用技巧
0.前言
本文章主要积累一些编程中常用的骗分技巧。可能是针对某些特殊的样例才有用,但是也有一定的道理,可能会给大家带来一些新的启示。
1.dfs常用技巧
1.1 适当剪枝
这个不说
1.2 添加返回条件
比如说一个程序只有达到某种条件时才会返回,但是因为条件太少,返回不多,就容易出现DFS爆栈的情况,所以需要增加条件。通常情况下,可以用增加阈值的情况来限制深搜的步骤。比如说:马的遍历 这道题,(很明显,这是一道BFS的题,但是如果真的要用dfs写的话,就很容易出现超时。)
比如我用如下的代码交这道题的时候,就有一个测试点超时。【如下图所示】
这时候如果真想用dfs交题就可以尝试添加一个dfs的返回条件。代码如下:
//count 代表马儿走了多少步
//(x,y) 代表当前的坐标值
void dfs(int x,int y ,int count){
if(x>n || x<1 || y<1 || y>m )//如果越界了
return ;
if(cur > 200)
return;
//肯定小,直接赋值
f[x][y] = count;
if(count+1 < f[x-2][y+1]) dfs(x-2,y+1,count+1);//1 往右上
if(count+1 < f[x-1][y+2]) dfs(x-1,y+2,count+1);//2
if(count+1 < f[x+1][y+2]) dfs(x+1,y+2,count+1);//3
if(count+1 < f[x+2][y+1]) dfs(x+2,y+1,count+1);//4往右下
if(count+1 < f[x+2][y-1]) dfs(x+2,y-1,count+1);//5
if(count+1 < f[x+1][y-2]) dfs(x+1,y-2,count+1);//6
if(count+1 < f[x-1][y-2]) dfs(x-1,y-2,count+1);//7
if(count+1 < f[x-2][y-1]) dfs(x-2,y-1,count+1);//8往左上
}
其中的关键语句就是
if(cur > 200)
return;
添加完之后就可以AC了。
update on 20200303
其实上面说的这种情况其实本质上就是迭代加深搜索的应用,因为搜索的越深,时间就越费时间,但最优解可能在搜索树的另一半的很浅的分支上。这时就会导致搜索效率很低!这时如果能够很好的限制搜索高度,就会很快的得到问题解。【重复高度的搜索相比于指数增长的深度搜,还是很小的数字!】
2.输入技巧
2.1 for循环
for循环真的能控制输入次数吗?别被假象迷惑!
给出下面一段程序,已经输入数据,判断是否ok。
void test5(){
int n;
cin >> n;
int arr[2*n];
for (int i = 1;i<=n+n;i++ ){
cin >> arr[i];
arr[i+n] = arr[i];
}
cout <<"=========\n";
for (int i = 1;i<=n+n;i++ ){
cout << arr[i]<<" ";
}
}
输入及执行结果如下:
可以看到这里只输入了3项,但是n=3,其实for循环中要输入6项才对!但是为啥这么做也行呢?因为程序碰到了输入结束符(EOF),也就是图中表示的^Z
,所以程序就会认为输入已经终止了。
这样的操作有什么用吗?当然有!当我们在处理一个环时,因为头尾是相连的,我们就可以通过这种扩大两倍的方式来简化头尾的处理。