Vital Algorithms: ZJU Programming test

本人2023年上岸浙大计算机学院专硕,无算法竞赛基础在初试后准备机试最后拿到了95分。学习和刷题过程中总结了一些板子题,发到csdn平台上供后来人借鉴。若有错误请指正。

感谢acwing平台的y总,他的算法思想和代码风格给了我备考过程中最大的帮助。

1.Dijkstra:两层循环,内部先选最小距离点,再标记“已访问”,最后更新距离数组

void dijkstra(int root)
{
    memset(dist,0x3f,sizeof dist);
    memset(st,0,sizeof st);
    dist[root]=0;
    for (int i=0;i<n;i++)
    {
        int t=-1;
        for (int j=1;j<=n;j++)
        {
            if (!st[j] && (t==-1 || dist[j]<dist[t]))
                t=j;
        }
        st[t]=1;
        for (int j=1;j<=n;j++)
        {
            if (dist[t]+graph[t][j]<dist[j])
                dist[j]=dist[t]+graph[t][j];
        }
    }
}

2.bfs+层次标记(dist数组写距离,每层在刚刚弹出的元素里面+1,刚好借助这个模板熟练bfs)

vector<int> graph[N];
int dist[N];
int bfs(int root,int aim)
{
    memset(dist,-1,sizeof dist);
  	dist[root]=0;
  	queue<int> q;
  	q.push(root);
  	while (q.size())
  	{
      	int t=q.front();
      	q.pop();
      	for (auto a:graph[t])
      	{
          	if (dist[a]==-1)
          	{
              	q.push(a);
                dist[a]=dist[t]+1;
          	}
      	}
    }
  	return dist[aim];
}

3.树的构建(in+post为例),in+pre类似(取pl点为根),分治法递归

int post[N],tree[N],le[N],ri[N];
unordered_map<int,int> pos;
int construct(int il,int ir,int pl,int pr)
{
  	int k=pos[post[pr]];
  	if (il<k)
      	le[k]=construct(il,k-1,pl,pl+(k-1-il));
  	else
      	le[k]=-1;
  	if (k<ir)
      	ri[k]=construct(k+1,ir,pr-1-(ir-k-1),pr-1);
  	else
      	ri[k]=-1;
  	return k;
}

4.并查集,收录两个操作:union&find

void union(int a,int b)
{
  	int pa=find(a);
  	int pb=find(b);
  	if (pa!=pb)
      	p[pa]=pb;
}

int find(int x)
{
  	if (x!=p[x])
      	p[x]=find(p[x]);
  	return p[x];
}

5.二分法

// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
    while (l<r)
    {
        int mid=l+r >> 1;
        if (check(mid)) r=mid;    // check()判断mid是否满足性质
        else l=mid+1;
    }
    return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{
    while (l<r)
    {
        int mid=l+r+1 >> 1;
        if (check(mid)) l=mid;
        else r=mid-1;
    }
    return l;
}
//浮点数:注意不要用等号
double bsearch_3(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

6.dfs+路径储存(如果不选择输出,也可以压入二级vector),注意“恢复现场”的递归思想

int n;
int path[N];
bool st[N];
void dfs(int u)
{
  	if (u==n)
  	{
      	for (int i=0;i<n;i++)
          	cout<<path[i];
      	cout<<endl;
      	return;
    }
  	for (int i=1;i<=n;i++)
  	{
      	if (!st[i])
      	{
          	path[u]=i;//路径写入
          	st[i]=1;//标记“已访问”
          	dfs(u+1);//递归
          	st[i]=0;//恢复现场
      	}
  	}
}

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值