DFS递归+递归函数模板+vector的注意事项

 DFS模板

void dfs() 
{
	// 写终止条件,即递归到什么时候停止,比如二叉树中子树为空,矩阵路径
	// 中超出地图边界等等,当然根据问题不同这个地方也会有些变化
	if ()
		return;
	
	// 递归与当前节点相连的要搜索的点。比如说矩阵路径中的上下左右四个点
	// 又或者父节点的左右子节点
    //一般是循环的形式
    for()
    {
        if()    //符合条件
        {
            // 为了防止反复遍历遍历过的节点,把遍历过的点标记
        	visited=true;
            //往下递归
        	dfs();    
        	//回溯
        	visited=false;
        }
    }


	return;
}

 4213. 最小结果 - AcWing题库

本题不同于一般的DFS递归
这里的数组范围是变化的(每往下递归一层就少一个数)
所以用vector存储数据

 代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long LL;

const LL INF = 1e15; 

char op[3];
LL res = INF;

void dfs(vector<LL> v, int u)  //u表示当前第操作的字符
{
    //结束条件
    if(v.size() == 1)//u>=3
    {
        res = min(res, v[0]);
        return ;
    }
    
    //循环
    for(int i = 0; i < v.size(); i ++ )
    {
        for(int j = i + 1; j < v.size(); j ++ )//不需要从0开始就能查找所有情况
        {
            vector<LL> t;
            if(op[u] == '+')    t.push_back(v[i] + v[j]);
            else    t.push_back(v[i] * v[j]);
            for(int k = 0; k < v.size(); k ++ )
                if(k != i && k != j)    t.push_back(v[k]);
            dfs(t, u + 1);
        }
        //无需回溯
    }
}

int main()
{
    vector<LL> v(4);
    for(int i = 0; i < 4; i ++ )    cin >> v[i];
    for(int i = 0; i < 3; i ++ )    cin >> op[i];
    
    dfs(v, 0);
    
    cout << res << endl;
    
    return 0;
}


   

使用vector的注意事项(切记):

  1. 使用 vector<int> v; 声明一个容器v时,如果没有给他预定存储空间(如:vector<int> v;),则可以直接使用v.push_back(x)插入变量x,那么插入的第一个元素可以用v[0]访问到。
  2. 使用 vector<int> v(n); 声明一个容器v时,如果给他预定存储空间(如:vector<int> v(n);),则vector<int> v(n) 等价于vector<int> v(n,0); 如果要使得位置0存储元素x,则只能使用v[0]=x,如果使用v.insert(x)插入变量x,那么v的第一个元素还是0,即v[0]=0,因为v.push_back(x)是将x插入到v[n],又因为声明v时,v最多能存储n个元素,即x根本没有成功插入容器v中。
    vector<int> v;
    v.push_back(1);//只能这样赋值,不能用v[0]=1;
     
    vector<int> v(n);//等价于vector<int> v(n,0);
    v[0]=1;//只能这样赋值,不能用v.push_back(1),因为此时的v.push_back(1)是把1插入到v[n]位置,但是v[n]越界了,实际上是无法插入的;
     
    vector<int> v(n,0);
    v[0]=1;//只能这样赋值,不能用v.push_back(1);
    
    //在输出的时候,两种方式都可以用数组的方式输出,也都可以使用v.back()获取最后一个元素的值


vector删除元素

iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);

vector中删除一个元素(position),或者范围元素( [first, last) )

参数:

position :iterator 指向vector 中要删除元素的位置。 

iterator first,last :iterator指向要删除范围。

position

Iterator pointing to a single element to be removed from the vector.
Member types iterator and const_iterator are random access iterator types that point to elements.

first, last

Iterators specifying a range within the vector] to be removed: [first,last). i.e., the range includes all the elements between first and last, including the element pointed by first but not the one pointed by last.
Member types iterator and const_iterator are random access iterator types that point to elements.

返回值:

返回一个iterator ,指向删除元素的下一个元素。所以在用for循环删除元素时,迭代器不用++指向下一个元素,erase()执行后,自动返回一个迭代器指向下一个元素。

例子:

#include<vector>
#include<iostream>
int main()
{
    vector<int> myvector;
    for(int i=0;i<20;i++)
        {
            myvector.push_back(i);
        }
    myvector.erase(myvector.begin()+2);//删除第三个元素
    myvecotr.erase(myvector.begin(),myvector.bengin()+3);//删除前3个元素,[ .. ),第四个元素没有删除
    for(auto it=myvector.begin();it!=myvecotr.begin()+5;)
        {
            myvector.erase(it);
        }
    for(auto it=myvector.begin();it!=myvcetor.end();it++)
        cout<<*it<<endl;
    //元素显示第二种方式,直接用索引来做
    //for(unsigned int i=0;i<myvector.size();i++)
    //cout<<' '<<myvector[i]
}


 

posted @ 2022-05-05 08:41  光風霽月  阅读(35)  评论(0编辑  收藏  举报