- L2-004 :这是二叉搜索树吗?
考点是二叉搜索树的表示。
请查看OI-WIKI中的文章:
树基础
include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int dat[N], n;
int ans1[N], ans2[N], ans1count, ans2count;
bool check1(int l, int r)//判断二叉搜索树的前序遍历
{
int x = dat[l];
if(l > r)return 1;
if(l == r)
{
ans1[ans1count++] = x;
return 1;
}
int i, j;
for(i = l+1; i <= r && dat[i] < x; i++) ;
i--;
for(j = i+1; j <= r && dat[j] >= x; j++) ;
j--;
if(j != r)return 0;
bool fig = check1(l+1, i)&check1(i+1,r);
/*
上面这行代码相当巧妙,既体现了递归性质,又存储了树的后序遍历。
只有check1返回才能执行check2,得以以左右根的方式进行存储。
*/
ans1[ans1count++] = x;
return fig;
}
bool check2(int l, int r)//判断镜像二叉搜索树的前序遍历
{
int x = dat[l];
if(l > r)return 1;
if(l == r)
{
ans2[ans2count++] = x;
return 1;
}
int i, j;
for(i = l+1; i <= r && dat[i] >= x; i++) ;
i--;
for(j = i+1; j <= r && dat[j] < x; j++) ;
j--;
if(j != r)return 0;
bool fig = check2(l+1, i)&check2(i+1,r);
ans2[ans2count++] = x;
return fig;
}
int main()
{
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> dat[i];
}
if(check1(0, n-1))
{
cout << "YES\n";
for (int i = 0; i < ans1count; i++)
{
if(i) cout << ' ';
cout << ans1[i];
}
}
else if(check2(0,n-1))
{
cout << "YES\n";
for (int i = 0; i < ans2count; i++)
{
if(i) cout << ' ';
cout << ans2[i];
}
}
else cout << "NO\n";
return 0;
}
/*
7
8 6 5 7 10 8 11 3
*/
- L2-005: 集合相似度
考你读题能力。
Nc是两个集合都有的不相等整数的个数
人话:在两个集合中都存在的元素有几种。
Nt是两个集合一共有的不相等整数的个数:
人话:两个集合中的元素种类数 - Nc
复习map的一些操作:
基于红黑树的STL容器,存储键值对。
基本操作:
map<key, value> mp;
插入键值对insert(key, value);
删除erase(key);
查找key对应的迭代器位置it = find(key);
查找key对应的值 operator[key];
判断key的数量count(key);只返回0,1.
.size() .begin() .end() .empty() .clear()与其他STL容器比较相似。
取值操作时一定要保证key存在:
if(mp.count(key)) cout << mp[key] << '\n';
使用map遍历有两种方式:
//c++11
for(auto &i : mp)
{
cout << i.first << ' ' << i.second();
}
//迭代器遍历
for(map<key, value>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << it->fisrt << ' ' << it->second;
}
AC代码如下:
include<bits/stdc++.h>
using namespace std;
map<int,bool> dat[55];//用map存储集合,因为集合容量过大
int main()
{
int n; cin >> n;
for(int i = 1; i <= n; i++)
{
int m; cin >> m;
for (int j = 1; j <= m; j++)
{
int x; cin >> x;
dat[i][x] = 1;
}
}
int k; cin >> k;
while(k--)
{
int a, b; cin >> a >> b;
int total = dat[a].size()+dat[b].size();
int ss = 0;
for(map<int,bool>:: iterator it = dat[a].begin(); it != dat[a].end(); it++)//迭代器遍历
{
if(dat[b].count(it->first) == 1) ss++;
}
printf("%.2lf%\n",100.0*ss/(total-ss));
}
return 0;
}
- L2-007: 家庭房产
么什么好说,就是一道长模拟......
复习一下并查集代码:
//并查集用来解决连通块问题。
int fa[N];
int find_root(int x) {return fa[x] == x ? x : find_root(fa[x])};
int main()
{
//链接u,v;
int u, v; cin >> u >> v;
fa[find_root(u)] = fa[v];
//判断a, b的亲属关系
int a, b; cin >> a >> b;
if(find_root(a) == find_root(b)) cout << "Yes\n";
else cout << "No\n";
return 0;
}
AC代码如下:
include<bits/stdc++.h>
using namespace std;
const int N = 10010;
int fa[N], peoplenum[N], housenum[N], areanum[N];
vector
struct nod
{
int id, people_num, house_num, area_num;
double perhousenum, perareanum;
bool operator < (const nod & b) const
{
if(perareanum!=b.perareanum) return perareanum > b.perareanum;
else return id < b.id;
};
};
vector
//并查集
int find(int x) {if(fa[x] == -1)return -1; return fa[x] == x ? x : fa[x] = find(fa[x]);}
void merge(int x, int y)
{
int xx = find(x), yy = find(y);
if(xx == yy)return;
if(xx > yy) swap(xx, yy);
fa[yy] = xx;
peoplenum[xx] += peoplenum[yy];
housenum[xx] += housenum[yy];
areanum[xx] += areanum[yy];
return;
}
int main()
{
int n; cin >> n;
fa[0] = -1;
for(int i = 0 ;i < n; i++)
{
int tid, dad, mom, sonk, son;
cin >> tid >> dad >> mom >> sonk;
for(int j = 0; j < sonk; j++)
{
cin >> son;
ship[tid].push_back(son);
fa[son] = son;
peoplenum[son] = 1;
}
if(dad != -1)
{
ship[tid].push_back(dad);
fa[dad] = dad;
peoplenum[dad] = 1;
}
if(mom != -1)
{
ship[tid].push_back(mom);
fa[mom] = mom;
peoplenum[mom] = 1;
}
fa[tid] = tid, peoplenum[tid] = 1;
cin >> housenum[tid] >> areanum[tid];
}
for(int i = 0; i <10000; i++)
{
for(int j = 0; j < ship[i].size(); j++)
{
merge(i,ship[i][j]);
}
}
for(int i = 0; i < 10000; i++)
{
if(i == find(i))
{
dat.push_back({i, peoplenum[i], housenum[i], areanum[i], 1.0*housenum[i]/peoplenum[i], 1.0*areanum[i]/peoplenum[i]});
}
}
sort(dat.begin(), dat.end());
printf("%d\n", dat.size());
for (int i = 0; i < dat.size(); i++)
{
printf("%04d %d %.3lf %.3lf\n", dat[i].id, dat[i].people_num, dat[i].perhousenum, dat[i].perareanum);
}
return 0;
}
明天把知识点写上。。。
浙公网安备 33010602011771号