算法复习一点点

博主分享了CCF比赛中的经验,包括数据结构与算法部分的解题策略,重点介绍了求解均值、方差和组合问题的代码实现。提到了使用double类型提高精度的方法,并提及了坐标变换问题的解决方案。最后预习了回溯算法在组合问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两天相继考了数据结构,系统,离散,终于要考算法了
因为数据结构在做往年题目,而且算法一般占比不多,所有没有更新blog,在快要考算法的前夕,继续更新blog

ccf2022-6-2

首先把上次ccf答的题目贴出来(当然,作为菜狗只AC了两道)
ccf现在可以边考边看自己拿了多少分了,挺不错的欸
第一题非常简单,只要设为double就可以过了,虽然精度没有示例那么高
如果精度要再高的话,我想到的一种办法是先乘pow(10,n)再运算,最后除回来,精度就会比较高了

#include<bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin>>n;
	
	double a[n];//存输入数字
	double avr=0;//均值
	
	for(int i=0;i<n;i++) {
		cin>>a[i];
		avr+=a[i];
	} 
	avr/=(double)n;//算均值
	
	//cout<<"avr: "<<avr<<endl;
	
	double da=0;//方差
	
	for(int i=0;i<n;i++) {
		da+=(a[i]-avr)*(a[i]-avr);
	} 
	da/=(double)n;
	
	//cout<<"da: "<<da<<endl;
	
	double sq=sqrt(da);//标准差
	
	//cout<<"sq: "<<sq<<endl;
	for(int i=0;i<n;i++) {
		cout<<(a[i]-avr)/sq<<endl;
	} 
	
	
	return 0;
}

第二题,坐标变换,可以写得很简单。

#include<bits/stdc++.h>
using namespace std;
/*
绿化图的范围大的时候,不能简单数组模拟。可以对照藏宝图每一个树的位置是否在绿化图里出现过,这样复杂度是S方,就可以AC了
*/


int treep[10000][2];//存绿化图树的坐标(x,y) 

map<int,bool> mp;//建立key与是否有树的映射

int main() {
	int n,L,S;
	cin>>n>>L>>S;
	
	 for(int i=0;i<n;i++) {
	 	cin>>treep[i][0];
	 	cin>>treep[i][1];
	 	int p=treep[i][0]*100000+treep[i][1];//用输入的树的坐标计算key值
	 	mp[p]=1;//建立该树的映射
	 	//mp.push_back();
	 }
	 
	
	int g[S+1][S+1];//藏宝图
	
	for(int i=S;i>=0;i--) {//输入藏宝图
		for(int j=0;j<=S;j++) {
			cin>>g[i][j];
		}
	} 
	

	
	int res[n];//答案数组
	for(int i=0;i<n;i++) res[i]=1;//初始化
	
	for(int i=0;i<n;i++) {
	     //检查下标是否越界
		if(treep[i][0]+S>L||treep[i][1]+S>L) {
			res[i]=0;
			continue;
		}
		//没越界就遍历藏宝图
		for(int j=0;j<=S;j++) {
			for(int k=0;k<=S;k++) {
				int x=treep[i][0]+j;
				int y=treep[i][1]+k;//藏宝图坐标转化为绿化图坐标
				
				int p=x*100000+y;//计算当前坐标对应的Key
				
					
				if(g[j][k]==1&&mp[p]==0) {//藏宝图有树绿化图无树
					 res[i]=0;
				}
				else if(g[j][k]==0&&mp[p]==1) {//藏宝图无数绿化图有树
					res[i]=0; 
				}
				
				}
		}

	}
	
	//遍历数组计算和
	int sum=0;
	for(int i=0;i<n;i++) {
		sum+=res[i];
	}
	
	cout<<sum;
	
	return 0;
}

先热热身,吃饭睡觉,下午继续来复习算法
呵~果然玩耍了一个下午,不愧是我(变形.jpg)

回溯算法解组合问题的两种方法

官方题解(子集树)

vector<int> temp;
vector<vector<int> > ans;
void bfs(int cur,int n,int k) {//递归索引cur为当前数字,由于按顺序排列的特殊性,该索引可以同时标记当前数字与当前数字所在位置
/*结果存储,函数声明,递归变量*/
	if(temp.size()+(n-cur+1)<k) return;//终止无穷递归,以及剪枝
	if(temp.size()==k) {res.push_back(path); return; }//存结果
	
	temp.push_back(cur)
	dfs(cur+1,n,k);//选择装当前货物的分支

	temp.pop();
	dfs(cur+1,n,k);//选择不装当前货物的分支

} 

代码随想录版本(排列树)

    vector<int> path;
    vector<vector<int> > res;
    vector<vector<int>> combine(int n, int k) {
        backtracking(1,n,k);
        return res;
    }
    void backtracking(int cur,int n,int k) {
        //if(path.size()+(n-cur+1)<k) return;//剩下数字个数加已有数字不够规定个数
        if(path.size()==k) {
            res.push_back(path);//大小相同装入答案
            return;
            }

        for(int i=cur;i<=n;i++) { 
            path.push_back(i);
            backtracking(i+1,n,k);//之前出错的原因是写成backtracking(cur+1,n,k)了
            path.pop_back();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值