Daliy Algorithm (greedy, BST , STL)-- day 88
Nothing to fear
种一棵树最好的时间是十年前,其次是现在!
那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~
2020.6.24
人一我十,人十我百,追逐青春的梦想,怀着自信的心,永不言弃!
GPLT-L2-003 月饼
贪心 + 模拟没啥说的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <vector>
using namespace std;
const int N = 5005;
struct node{
double kucun = 0;
double price = 0;
double profit = 0;
void getPorfit(){
profit = price / kucun;
}
}a[N];
bool cmp(node a,node b)
{
return a.profit > b.profit;
}
int main()
{
int n ;
double d;
cin >> n >> d;
for(int i = 0;i < n ;i ++){
cin >> a[i].kucun;
}
for(int i = 0;i < n ;i ++){
cin >> a[i].price;
a[i].getPorfit();
}
sort(a , a + n ,cmp);
int index = 0;double ans = 0;
while(d - a[index].kucun >= 0 && index < n)
{
if(a[index].kucun > 0)
{
d -= a[index].kucun;
ans += a[index].price;
}
index++;
}
if(d > 0 && a[index].kucun > 0){
ans += a[index].price / (a[index].kucun / d);
}
printf("%.2f\n",ans);
return 0;
}
GPLT-L2-004 这是二叉搜索树吗?
思路:
如果是先序序列那么第一个一定是根结点
我们需要根据二叉搜索树的性质即:
- 根的左子树的值一定小于等于根
- 根的右子树的值一定大于等于根
要根据这个性质划分出左右子树
然后按照树地遍历规则去不断递归将根结点地
顺序放入post中如果长度 == n说明符合
如果不等于说明可能是镜像序列需要根据镜像规则遍历
关键在于划分子树:
i = root + 1, j = tail
如果是正常序列
找到第一个大于root 的元素的位置
找到最后一个小于等于 root的位置
如果是镜像序列
找到最后一个小于等于根的位置
以及第一个大于根的位置 这样不会拉下重复元素的情况
并且将其都放在了根的左子树上。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1005;
vector<int> pre , post;
bool isMirror = false;
int n;
void getpost(int root , int tail)
{
if(root > tail)return;
int i = root + 1, j = tail;
if(!isMirror)
{
while(i <= tail && pre[root] > pre[i])i++;
while(j > root && pre[root] <= pre[j])j--;
}else {
while(i <= tail && pre[root] <= pre[i])i++;
while(j > root && pre[root] > pre[j]) j--;
}
if(i - j != 1)return;
getpost(root + 1 , j);
getpost(i , tail);
post.push_back(pre[root]);
}
int main()
{
cin >> n;
pre.resize(n);
for(int i = 0 ;i < n ;i ++)
cin >> pre[i];
getpost(0 , n - 1);
if(post.size() != n)
{
isMirror = true;
post.clear();
getpost(0 , n - 1);
}
if(post.size() == n)
{
printf("YES\n%d",post[0]);
for(int i = 1;i < n ;i ++)
{
printf(" %d", post[i]);
}
}else printf("NO\n");
return 0;
}
GPLT-L2-005 集合相似度
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <set>
#include <cmath>
using namespace std;
int n , k;
const int N = 10005;
vector<set<int>> v;
void query(int x,int y)
{
int nc = 0,nt = v[y].size();
for(auto it = v[x].begin() ; it != v[x].end(); it++)
{
if(v[y].find(*it) == v[y].end())nt++;
else nc++;
}
double ans = nc * 1.0 / nt * 100;
printf("%.2f%\n",ans);
}
void input()
{
cin >> n ;int t;
v.resize(n + 1);
for(int i = 1;i <= n ;i ++)
{
cin >> t;set<int> s;int x;
for(int j = 0;j < t ;j ++)
{
cin >> x;
s.insert(x);
}
v[i] = s;
}
cin >> k;
while(k --)
{
int a , b;
cin >> a >> b;
query(a , b);
}
}
int main()
{
input();
return 0;
}