这两天相继考了数据结构,系统,离散,终于要考算法了
因为数据结构在做往年题目,而且算法一般占比不多,所有没有更新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();
}
}