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 这是二叉搜索树吗?

思路:
如果是先序序列那么第一个一定是根结点
我们需要根据二叉搜索树的性质即:

  1. 根的左子树的值一定小于等于根
  2. 根的右子树的值一定大于等于根

要根据这个性质划分出左右子树
然后按照树地遍历规则去不断递归将根结点地
顺序放入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;
}
posted @ 2020-06-24 22:15  _starsky  阅读(94)  评论(0编辑  收藏  举报