2015长春网络赛

1001 (优先队列)

Alisha’s Party

Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2665    Accepted Submission(s): 725


Problem Description
Princess Alisha invites her friends to come to her birthday party. Each of her friends will bring a gift of some value v , and all of them will come at a different time. Because the lobby is not large enough, Alisha can only let a few people in at a time. She decides to let the person whose gift has the highest value enter first.

Each time when Alisha opens the door, she can decide to let p people enter her castle. If there are less than p people in the lobby, then all of them would enter. And after all of her friends has arrived, Alisha will open the door again and this time every friend who has not entered yet would enter.

If there are two friends who bring gifts of the same value, then the one who comes first should enter first. Given a query n Please tell Alisha who the nth person to enter her castle is.
 

Input
The first line of the input gives the number of test cases, T , where 1T15 .

In each test case, the first line contains three numbers k,m and q separated by blanks. k is the number of her friends invited where 1k150,000 . The door would open m times before all Alisha’s friends arrive where 0mk . Alisha will have q queries where 1q100 .

The ith of the following k lines gives a string Bi , which consists of no more than 200 English characters, and an integer vi , 1vi108 , separated by a blank. Bi is the name of the ith person coming to Alisha’s party and Bi brings a gift of value vi .

Each of the following m lines contains two integers t(1tk) and p(0pk) separated by a blank. The door will open right after the tth person arrives, and Alisha will let p friends enter her castle.

The last line of each test case will contain q numbers n1,...,nq separated by a space, which means Alisha wants to know who are the n1th,...,nqth friends to enter her castle.

Note: there will be at most two test cases containing n>10000 .
 

Output
For each test case, output the corresponding name of Alisha’s query, separated by a space.
 

Sample Input
  
  
1 5 2 3 Sorey 3 Rose 3 Maltran 3 Lailah 5 Mikleo 6 1 1 4 2 1 2 3
 

Sample Output
  
  
Sorey Lailah Rose
 

Source
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5449  5448  5447  5446  5445

#include <iostream>
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "algorithm"
#include "queue"
#define N 50005
using namespace std;

struct node{
    char name[205];
    int val,id;
    bool operator <(const struct node a) const
    {
        return val==a.val?id>a.id:val<a.val;
    }
}mess[150005],to[150005];
struct pnode{
    int t,p;
    bool operator < (const struct pnode a) const
    {
        return t<a.t;
    }
}en[150005];

int main(void)
{
    int T;
    int query[105];
    scanf("%d",&T);
    while(T--)
    {
        priority_queue <struct node> qq;
        int k,m,q,maxn;

        maxn=0;
        scanf("%d%d%d",&k,&m,&q);
        for(int i=0;i<k;i++)
        {
            scanf("%s%d",mess[i].name,&mess[i].val);
            mess[i].id=i;
        }

        for(int i=0;i<m;i++)
            scanf("%d%d",&en[i].t,&en[i].p);
        en[m].t=k;en[m].p=k;

        for(int i=0;i<q;i++)
        {
            scanf("%d",&query[i]);
            maxn=max(query[i],maxn);
        }

        sort(en,en+m);
        int op,pos;
        op=0;pos=1;
        for(int i=0;i<=m;i++)
        {
            while(op<en[i].t)
            {
                qq.push(mess[op++]);
            }

            while(!qq.empty() && en[i].p-- && pos<=maxn)
            {
                to[pos++]=qq.top();
                qq.pop();
            }
            if(pos>maxn) break;
        }
        for(int i=0;i<q-1;i++)
            printf("%s ",to[query[i]].name);
        printf("%s\n",to[query[q-1]].name);
    }
}
1002 (类似于拓扑排序的删点+dfs)

Ponds

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1918    Accepted Submission(s): 605


Problem Description
Betty owns a lot of ponds, some of them are connected with other ponds by pipes, and there will not be more than one pipe between two ponds. Each pond has a value v .

Now Betty wants to remove some ponds because she does not have enough money. But each time when she removes a pond, she can only remove the ponds which are connected with less than two ponds, or the pond will explode.

Note that Betty should keep removing ponds until no more ponds can be removed. After that, please help her calculate the sum of the value for each connected component consisting of a odd number of ponds
 

Input
The first line of input will contain a number T(1T30) which is the number of test cases.

For each test case, the first line contains two number separated by a blank. One is the number p(1p104) which represents the number of ponds she owns, and the other is the number m(1m105) which represents the number of pipes.

The next line contains p numbers v1,...,vp , where vi(1vi108) indicating the value of pond i .

Each of the last m lines contain two numbers a and b , which indicates that pond a and pond b are connected by a pipe.
 

Output
For each test case, output the sum of the value of all connected components consisting of odd number of ponds after removing all the ponds connected with less than two pipes.
 

Sample Input
  
  
1 7 7 1 2 3 4 5 6 7 1 4 1 5 4 5 2 3 2 6 3 6 2 7
 

Sample Output
  
  
21
 

Source
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5449  5448  5447  5446  5445

注意用long long 输出  int 会爆

//
//  main.c
//  example
//
//  Created by Adam on 15/2/2.
//  Copyright (c) 2015年 Adam. All rights reserved.
//


#include <stdio.h>
#include "string.h"

int v[10005];
int rudu[10005],vis[10005];
int pre[100005],cnt,tmp;
long long sum;
struct node{
    int to,next;
}T[100005];

void add(int a,int b)
{
    T[cnt].to=b;
    T[cnt].next=pre[a];
    pre[a]=cnt++;
}

void dfs(int a)
{
    vis[a]=1;tmp++;
    sum+=v[a];
    for(int i=pre[a];i!=-1;i=T[i].next)
    {
        int temp=T[i].to;
        if(vis[temp]==1||rudu[temp]==-1) continue;
        dfs(temp);
    }
}

int main(void)
{
    int t,p,m,leap;
    long long int ans;
    
    scanf("%d",&t);
    while(t--)
    {
        ans=0;cnt=0;
        memset(pre,-1,sizeof pre);
        memset(rudu,0,sizeof rudu);
        memset(vis, 0, sizeof(vis));
        scanf("%d%d",&p,&m);
        for(int i=1;i<=p;i++)
        {
            scanf("%d",&v[i]);
        }
        int a,b;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            rudu[a]++;rudu[b]++;
            add(a,b);
            add(b,a);
        }
        for(int i=1;i<=p;i++)
            if(rudu[i]==0) rudu[i]=-1;
        leap=1;
        while(leap)
        {
            leap=0;
            for(int i=1;i<=p;i++)
                if(rudu[i]!=-1&&rudu[i]<=1){
                    rudu[i]=-1;
                    for(int k=pre[i];k!=-1;k=T[k].next)
                        if(rudu[T[k].to]!=-1) rudu[T[k].to]--;
                    leap=1;
                    break;
                }
        }
        for(int i=1;i<=p;i++)
            if(!vis[i]&&rudu[i]!=-1){
                sum=0;tmp=0;
                dfs(i);
                if(tmp&1) ans+=sum;
            }
        printf("%lld\n",ans);
    }
}

1005(并查集)

Travel

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1678    Accepted Submission(s): 591


Problem Description
Jack likes to travel around the world, but he doesn’t like to wait. Now, he is traveling in the Undirected Kingdom. There are n cities and m bidirectional roads connecting the cities. Jack hates waiting too long on the bus, but he can rest at every city. Jack can only stand staying on the bus for a limited time and will go berserk after that. Assuming you know the time it takes to go from one city to another and that the time Jack can stand staying on a bus is x minutes, how many pairs of city (a,b) are there that Jack can travel from city a to b without going berserk?
 

Input
The first line contains one integer T,T5 , which represents the number of test case.

For each test case, the first line consists of three integers n,m and q where n20000,m100000,q5000 . The Undirected Kingdom has n cities and m bidirectional roads, and there are q queries.

Each of the following m lines consists of three integers a,b and d where a,b{1,...,n} and d100000 . It takes Jack d minutes to travel from city a to city b and vice versa.

Then q lines follow. Each of them is a query consisting of an integer x where x is the time limit before Jack goes berserk.

 

Output
You should print q lines for each test case. Each of them contains one integer as the number of pair of cities (a,b) which Jack may travel from a to b within the time limit x .

Note that (a,b) and (b,a) are counted as different pairs and a and b must be different cities.
 

Sample Input
  
  
1 5 5 3 2 3 6334 1 5 15724 3 5 5705 4 3 12382 1 3 21726 6000 10000 13000
 

Sample Output
  
  
2 6 12
 

Source
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5449  5448  5447  5446  5445 
 
#include <iostream>
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "algorithm"
#include "queue"
#define N 50005
using namespace std;
int n,m,q;
int father[20005],sum[20005],answer[5005];

struct node {
    int op,ed,v;
    bool operator <(const struct node a)const
    {
        return v<a.v;
    }
}edge[100005];

struct pnode{
    int val,id;
    bool operator <(const struct pnode a) const
    {
        return val<a.val;
    }
}query[5005];
int find_(int a)
{
    return father[a]==a?a:father[a]=find_(father[a]);
}

int main()
{
    int t;
    long long ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=n;i++)
        {
            father[i]=i;
            sum[i]=1;
        }
        for(int i=0;i<m;i++)
            scanf("%d%d%d",&edge[i].op,&edge[i].ed,&edge[i].v);
        sort(edge,edge+m);
        int pos=0;
        ans=0;

        for(int i=0;i<q;i++)
        {
            scanf("%d",&query[i]);
            query[i].id=i;
        }
        sort(query,query+q);
        for(int i=0;i<q;i++)
        {
            int temp=query[i].val;
            for( ;temp>=edge[pos].v&&pos<m;pos++)
            {
                int a=find_(edge[pos].op),b=find_(edge[pos].ed);
                if(a==b) continue;
                ans+=sum[a]*sum[b];
                father[a]=b;
                sum[b]+=sum[a];
            }
            answer[query[i].id]=ans*2;
        }
        for(int i=0;i<q;i++)
            printf("%d\n",answer[i]);
    }
    return 0;
}
1007(暴力即可)

The Water Problem

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 684    Accepted Submission(s): 544


Problem Description
In Land waterless, water is a very limited resource. People always fight for the biggest source of water. Given a sequence of water sources with a1,a2,a3,...,an representing the size of the water source. Given a set of queries each containing 2 integers l and r , please find out the biggest water source between al and ar .
 

Input
First you are given an integer T(T10) indicating the number of test cases. For each test case, there is a number n(0n1000) on a line representing the number of water sources. n integers follow, respectively a1,a2,a3,...,an , and each integer is in {1,...,106} . On the next line, there is a number q(0q1000) representing the number of queries. After that, there will be q lines with two integers l and r(1lrn) indicating the range of which you should find out the biggest water source.
 

Output
For each query, output an integer representing the size of the biggest water source.
 

Sample Input
  
  
3 1 100 1 1 1 5 1 2 3 4 5 5 1 2 1 3 2 4 3 4 3 5 3 1 999999 1 4 1 1 1 2 2 3 3 3
 

Sample Output
  
  
100 2 3 4 4 5 1 999999 999999 1
 

Source
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5449  5448  5447  5446  5445
#include <iostream>
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "algorithm"
#include "queue"
#define N 50005
using namespace std;
int ss[1005],l[1005],r[1005];

int main(void)
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,q;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&ss[i]);
        scanf("%d",&q);
        for(int i=0;i<q;i++)
            scanf("%d%d",&l[i],&r[i]);
        for(int i=0;i<q;i++)
        {
            int mx=0;
           for(int j=l[i];j<=r[i];j++)
                mx=max(ss[j],mx);
            printf("%d\n",mx);
        }
    }
}
1008 (暴力二叉搜索树即可)

Elven Postman

Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 820    Accepted Submission(s): 440


Problem Description
Elves are very peculiar creatures. As we all know, they can live for a very long time and their magical prowess are not something to be taken lightly. Also, they live on trees. However, there is something about them you may not know. Although delivering stuffs through magical teleportation is extremely convenient (much like emails). They still sometimes prefer other more “traditional” methods.

So, as a elven postman, it is crucial to understand how to deliver the mail to the correct room of the tree. The elven tree always branches into no more than two paths upon intersection, either in the east direction or the west. It coincidentally looks awfully like a binary tree we human computer scientist know. Not only that, when numbering the rooms, they always number the room number from the east-most position to the west. For rooms in the east are usually more preferable and more expensive due to they having the privilege to see the sunrise, which matters a lot in elven culture.

Anyways, the elves usually wrote down all the rooms in a sequence at the root of the tree so that the postman may know how to deliver the mail. The sequence is written as follows, it will go straight to visit the east-most room and write down every room it encountered along the way. After the first room is reached, it will then go to the next unvisited east-most room, writing down every unvisited room on the way as well until all rooms are visited.

Your task is to determine how to reach a certain room given the sequence written on the root.

For instance, the sequence 2, 1, 4, 3 would be written on the root of the following tree.

 

Input
First you are given an integer T(T10) indicating the number of test cases.

For each test case, there is a number n(n1000) on a line representing the number of rooms in this tree. n integers representing the sequence written at the root follow, respectively a1,...,an where a1,...,an{1,...,n} .

On the next line, there is a number q representing the number of mails to be sent. After that, there will be q integers x1,...,xq indicating the destination room number of each mail.
 

Output
For each query, output a sequence of move ( E or W ) the postman needs to make to deliver the mail. For that E means that the postman should move up the eastern branch and W the western one. If the destination is on the root, just output a blank line would suffice.

Note that for simplicity, we assume the postman always starts from the root regardless of the room he had just visited.
 

Sample Input
  
  
2 4 2 1 4 3 3 1 2 3 6 6 5 4 3 2 1 1 1
 

Sample Output
  
  
E WE EEEEE
 

Source
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5449  5448  5447  5446  5445


#include <iostream>
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "algorithm"
#include "queue"
#define N 50005
using namespace std;

typedef struct node{
    int data;
    struct node *lc;
    struct node *rc;
}p;
p head;

void insert_(p **root,int x)
{
    if(*root==NULL){
        p * head=(p *)malloc(sizeof(p));
        head->data=x;
        head->lc=NULL;
        head->rc=NULL;
       * root=head;
       return ;
    }
    if(x<((*root)->data)) insert_(&((*root)->lc),x);
    else insert_(&((*root)->rc),x);
}
void search_(p *root,int x)
{
    if(x==root->data) printf("\n");
    else if(x<root->data) {
        printf("E");
        search_(root->lc,x);
    }
    else if(x>root->data){
        printf("W");
        search_(root->rc,x);
    }
}
int main(void)
{
    int t,query[1005];
    scanf("%d",&t);
    while(t--)
    {
        int a,q,n;
        p *head=NULL;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            insert_(&head,a);
        }
        scanf("%d",&q);
        for(int i=0;i<q;i++)
        {
            scanf("%d",&a);
            search_(head,a);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值