挑战程序设计竞赛 2.4 加工并存储数据的数据结构

【Summarize】

  1.求满足条件的情况下最大化中位数可以枚举中位数再验证条件

  2.对于种类并查集,可以利用拆点的方式,用x-A表示x属于A类,将种类归属关系作为节点进行运算

POJ 3614:Sunscreen

/*
    每个奶牛各自能够忍受的阳光强度有一个最小值和一个最大值
    防晒霜的作用是让阳光照在身上的阳光强度固定为某个值
    每瓶防晒霜给出固定的阳光量和防晒霜数量
    每头奶牛只能用一瓶防晒霜
    问最多能晒太阳的奶牛数量
*/
#include <cstdio>
#include <queue>
#include <algorithm>
const int N=3000;
using namespace std;
int n,m;
typedef pair<int,int> P;
priority_queue<int,vector<int>,greater<int> > q;
P cow[N],bottle[N];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)scanf("%d%d",&cow[i].first,&cow[i].second);
    for(int i=0;i<m;i++)scanf("%d%d",&bottle[i].first,&bottle[i].second);
    sort(cow,cow+n);sort(bottle,bottle+m);
    int j=0,ans=0;
    for(int i=0;i<m;i++){
        while(j<n&&cow[j].first<=bottle[i].first)q.push(cow[j++].second);
        while(!q.empty()&&bottle[i].second){
            int x=q.top(); q.pop();
            if(x<bottle[i].first)continue;
            ans++; bottle[i].second--;
        }
    }printf("%d\n",ans);
    return 0;
}  

POJ 2010:Moo University - Financial Aid

/*
    每个物品有两个属性值s和f,从m个物品中选取n个物品
    求f的和小于等于F的情况下s的中位数最大值。
    按照s排序,枚举每个s作为中位数的情况
    那么只要知道前面n/2最小值的和和后面n/2最小值的和就好
    这个可以利用优先队列预处理出来
*/
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
priority_queue<int> q;
const int N=100010;
int n,m,F,pre[N],nxt[N],sum;
struct data{int s,f;}p[N];
bool cmp(data a,data b){return a.s>b.s;}
int main(){
    scanf("%d%d%d",&n,&m,&F);
    for(int i=1;i<=m;i++)scanf("%d%d",&p[i].s,&p[i].f);
    sort(p+1,p+m+1,cmp);
    int base=n/2;
    for(int i=1;i<=base;i++)q.push(p[i].f),sum+=p[i].f;
    for(int i=base+1;i<=m-base;i++){
        pre[i]=sum;
        if(q.top()>p[i].f){
            sum-=q.top();
            q.pop();
            sum+=p[i].f;
            q.push(p[i].f);
        }
    }while(!q.empty())q.pop();sum=0;
    for(int i=m;i>m-base;i--)q.push(p[i].f),sum+=p[i].f;
    for(int i=m-base;i>=base+1;i--){
        nxt[i]=sum;
        if(q.top()>p[i].f){
            sum-=q.top();
            q.pop();
            sum+=p[i].f;
            q.push(p[i].f);
        }
    }int ans=-1;
    for(int i=base+1;i<=m-base;i++){
        if(p[i].f+pre[i]+nxt[i]<=F){
            ans=p[i].s;
            break;
        }
    }printf("%d\n",ans);
    return 0;
}

POJ 2236:Wireless Network

/*
    每台电脑可以连接到距离不超过d的正常电脑,连接具有传递性
    现在因为地震,所有的电脑被损坏了,现在进行维修电脑的行动
    O x表示维修好了编号为x的电脑,S x y表示查询x和y是否能连接
*/
#include <cstdio>
const int N=1010;
struct data{int x,y;}p[N];
int f[N],x,y,n,d,a[N];
char op[10];
int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
int sqr(int x){return x*x;}
bool link(int a,int b){return sqr(p[a].x-p[b].x)+sqr(p[a].y-p[b].y)<=d*d;}
int main(){
    scanf("%d%d",&n,&d);
    for(int i=1;i<=n;i++)f[i]=i,a[i]=0,scanf("%d%d",&p[i].x,&p[i].y);
    while(~scanf(" %s",op)){
        if(op[0]==‘O‘){
            scanf("%d",&x);
            for(int i=1;i<=n;i++)if(a[i]&&link(x,i)){
                if(sf(x)==sf(i))continue;
                f[sf(x)]=sf(i);
            }a[x]=1;
        }else{
            scanf("%d%d",&x,&y);
            if(sf(x)==sf(y))puts("SUCCESS");
            else puts("FAIL");
        }
    }return 0;
}

POJ 1703:Find them, Catch them

/*
    有两个物种,每个生物都属于两种物种之一,
    现在有两个操作,表示两个生物属于不同物种或者查询两个物种的关系
*/
#include <cstdio>
const int N=100010<<1;
int T,f[N],n,m,x,y;
char op[2];
void init(int n){for(int i=0;i<=n;i++)f[i]=i;}
int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}
bool Same(int x,int y){return sf(x)==sf(y);}
bool Union(int x,int y){f[sf(x)]=sf(y);}
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        init(2*n);
        for(int i=1;i<=m;i++){
            scanf(" %s%d%d",&op,&x,&y);
            x--;y--;
            if(op[0]==‘D‘){Union(x,y+n);Union(x+n,y);}
            else{
                if(Same(x,y)||Same(x+n,y+n))puts("In the same gang.");
                else if(Same(x,y+n)||Same(x+n,y))puts("In different gangs.");
                else puts("Not sure yet.");
            }
        }
    }return 0;
}

AOJ 2170:Marked Ancestor

/*
    给出一棵树,一开始根节点是上色的,
    现在有两个操作:给某个节点上色,或者查询一个节点最近的上色的祖先节点
*/
#include <cstdio>
const int N=100010;
int f[N],n,m,x;
char op[2];
int sf(int x){return f[x]==x?x:sf(f[x]);}
int main(){
    while(scanf("%d%d",&n,&m),n+m){
        for(int i=2;i<=n;i++)scanf("%d",&f[i]);
        long long ans=0; f[1]=1;
        while(m--){
            scanf(" %s%d",op,&x);
            if(op[0]==‘M‘)f[x]=x;
            else ans+=sf(x);
        }printf("%lld\n",ans);
    }return 0;
}

  

时间: 2024-10-01 04:14:40

挑战程序设计竞赛 2.4 加工并存储数据的数据结构的相关文章

《挑战程序设计竞赛》2.4 加工并存储数据的数据结构

这个章节一共介绍了几种数据结构:堆,二叉搜索树,并查集. 第一部分 堆. 堆的实现: int heap[maxn]; void push(int x) { int i = sz;//自己结点的编号 while(i > 0) { int p = (i - 1) / 2; if(heap[p] <= x) break; heap[i] = heap[p]; i = p; } heap[i] = x; } int pop() { int ret = heap[0];//取出优先级最高的元素 int

加工并存储数据的数据结构

堆 一些注意点:左儿子的编号是自己的编号*2+1右儿子的编号是自己的编号*2+2父亲节点的编号是(自己的编号-1)/2 手动实现的堆,贴一段书上的代码: 1 #include <iostream> 2 3 using namespace std; 4 5 int const MAX_N=233333; 6 int heap[MAX_N]; 7 int sz,n; 8 9 void push(int); 10 int pop(void); 11 12 int main() 13 { 14 cin

POJ 3420 Quad Tiling 题解 《挑战程序设计竞赛》

POJ 3420 Quad Tiling贴瓷砖:4*N的地板上用2*1的瓷砖铺满,求所有方案数对M求余.3.4熟练掌握动态规划矩阵的幂久违地上了节课,太无聊,只好刷一题.假设S[n]表示填满n时的方案数,有S[0]=1.定义矩阵M[p][q] := 边缘p和边缘q可以拼合时取1,否则取0所谓的可以拼合表示,两个边缘拼起来后长度为1(为2就拼接不起来了),且内部缝隙可以用2*1的瓷砖填满.那么M就有一些简单的性质了,比如M的第一行应该是:0 0 0 0 0 0... 继续阅读:码农场 » POJ

POJ 3411 Paid Roads 题解 《挑战程序设计竞赛》

POJ 3411 Paid Roads开路:N个城市间有m条单向路,分别从a到b,可以在c处交P路费,也可以直接交R路费.那么问题来了,你的挖掘机怎么开最省钱?3.4熟练掌握动态规划状态压缩DP乍一看可以Dijkstra,实际上的确可以Dijkstra.不过多了一个预交费的c,所以在遍历的时候多了一维状态,这个维度储存当前走过的城市集合.在Dijkstra的时候,如果走过了c那么就有两个选择,选其中最省的即可:否则没得选.#include <iostream> #include&nb.

字符串HASH模板 取自挑战程序设计竞赛(第2版)

/*===================================================* 从b串中寻找和a串长度相同的子串,返回开始位置 不保证绝对正确,发生冲突概率为O(sqrt(n)), n为哈希函数的最大值 \*===================================================*/ #define ull unsigned long long const ull B = 1e8+7; /*according to the book*/

[转] AOJ 0525 Osenbei《挑战程序设计竞赛(第2版)》练习题答案

来自 码农场 ? AOJ 0525 Osenbei<挑战程序设计竞赛(第2版)>练习题答案 只把代码复制过来,原博的其他分析请看链接. 1 #include <iostream> 2 #include <bitset> 3 #include <algorithm> 4 5 using namespace std; 6 7 bitset<10000> cookie[10]; 8 9 ///////////////////////////SubMai

POJ 2836 Rectangular Covering 题解 《挑战程序设计竞赛》

POJ 2836 Rectangular Covering铺地板:坐标平面上有n各点,用任意大小(非零)的地板砖覆盖它们,求最省的地板砖总面积.3.4熟练掌握动态规划状态压缩DP先预处理数据,将n个点两两组合形成n * (n-1) / 2个矩形,计算每个矩形的面积和内部点个数.接着利用预处理数据来枚举,定义dp[S] := 矩形集为S时的最省面积先假设平面上没有矩形,那么dp[0]=0,接着一个一个地往平面上加矩形,递推关系是:dp[新矩形集合] = min(dp[新矩形集合], dp[旧矩形集

poj2431 Expedition (优先队列) 挑战程序设计竞赛

题目链接:http://poj.org/problem?id=2431 Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9148   Accepted: 2673 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor driver

Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题

King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazingly, there are no roads in the kingdom now. Recently, he planned to construct roads between the capital and the cities, but it turned out that the con