码迷,mamicode.com
首页 > 其他好文 > 详细

2016 UESTC Training for Data Structures - xgtao -

时间:2016-08-02 00:51:04      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

郭大侠与Rabi-Ribi 

 

给出每一只兔子从1时刻消失的时间和权值,选择一只兔子就要消耗1的时间,能获得最大权值是多少?

 

先将把关于兔子消失的时间从小到大排序,维护一个T表示时间的流逝,如果某一只兔子还没有消失就直接加入优先队列,如果某一只兔子已经消失了并且它的权值比优先队列里面的最小值要大,那么就把最小值弹出,把这个兔子加入队列。

 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int N = 100010;

int n;
long long ans,T;
struct node{
	long long t,w;
	bool operator < (const node &rhs)const{return w > rhs.w;}
}x[N];

bool cmp(node a,node b){return a.t<b.t;}

priority_queue<node> q;

int main(){
	scanf("%d",&n);
	for(int i = 1;i <= n;++i)scanf("%lld",&x[i].t);
	for(int i = 1;i <= n;++i)scanf("%lld",&x[i].w);
	sort(x+1,x+n+1,cmp);
	q.push(x[1]);
	T++,ans = x[1].w;
	for(int i = 2;i <= n;++i){
		if(x[i].t <= T && x[i].w>q.top().w){
			node p = q.top();q.pop();
			ans = ans-p.w+x[i].w;
			q.push(x[i]);
		}
		else if(x[i].t > T){
			q.push(x[i]);
			ans += x[i].w;
			++T;
		}
	}
	printf("%lld\n",ans);
	return 0;
}

  

 

卿学姐与魔法

 

给出两个长度为n(<=100000)的数列,a[n],b[n],要求在a,b两个数列中选择n个最小的ai+bj(可重复选),从小到大输出。

 

将两个数列排序,将a[1~n]+b[1]压入优先队列,如果要取某一个数x(ai+bj)那么就把他弹出,并把x-bj+bj+1也就是ai+bj+1压入队列,一直操作n次。

 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 1000010;
struct node{
	int w,k;
	bool operator < (const node& rhs)const{return w > rhs.w;}
};
priority_queue<node>q;
int a[N],b[N],n,ans[N];

int main(){
	scanf("%d",&n);
	for(int i = 1;i <= n;++i)scanf("%d",&a[i]);
	for(int i = 1;i <= n;++i)scanf("%d",&b[i]);
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
	for(int i = 1;i <= n;++i)q.push(node{a[i]+b[1],1});
	for(int i = 1;i <= n;++i){
		node p = q.top();q.pop();
		ans[i] = p.w;
		if(p.k < n)q.push(node{p.w-b[p.k]+b[p.k+1],p.k+1});
	}
	sort(ans+1,ans+1+n);
	for(int i = 1;i <= n;++i)printf("%d\n",ans[i]);
	return 0;
}

  

 

卿学姐与诡异村庄

 

有n个人,分为好人坏人,好人只说真话,坏人只说假话,如果好人坏人说的话是否存在矛盾。

 

并查集可以表示从属关系,那么有两种类别,就开两倍的数组,fa[1~n]表示好人,fa[n+1~2*n]表示坏人,如果存在一个x使得fa[x] == fa[x+n]那么就是矛盾的,因为一个人不可能是好人又是坏人。

 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,fa[N<<1],y,grb;

int find(int x){
	return x == fa[x] ? x : find(fa[x]);
}

int main(){
	scanf("%d",&n);
	for(int i = 1;i <= 2*n;++i)fa[i] = i;
	for(int x = 1;x <= n;++x){
		scanf("%d%d",&y,&grb);
		if(grb == 1){
			int fx,fy;
			fx = find(x+n),fy = find(y+n);
			if(fx != fy)fa[fx] = fy;
			fx = find(x),fy = find(y);
			if(fx != fy)fa[fx] = fy;
		}
		else if(grb == 2){
			int fx,fy;
			fx = find(x+n),fy = find(y);
			if(fx != fy)fa[fx] = fy;
			fx = find(x),fy = find(y+n);
			if(fx != fy)fa[fx] = fy;
		}
	}
	bool flag = true;
	for(int i = 1;i <= n;++i){
		if(find(i) == find(i+n))flag =false;
	}
	if(!flag)printf("One face meng bi\n");
	else printf("Time to show my power\n");
	return 0;
}

2016 UESTC Training for Data Structures - xgtao -

标签:

原文地址:http://www.cnblogs.com/xgtao984/p/5727500.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!