La Salle-Pui Ching Programming Challenge 2017 Gym

来源:互联网 发布:为实现数据的保密性 编辑:程序博客网 时间:2024/05/29 12:31

A题:

计算模糊日期的天数,简单思维题,注意long long

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define LL long longint a[100005];int main(){    int n;    //freopen("in.txt","r",stdin);    while(scanf("%d",&n)!=EOF)    {        for(int i=0;i<n;i++)            scanf("%d",&a[i]);        sort(a,a+n);        LL ans=0;        for(int i=0;i<n;i++)            if((min(n,a[i])-i-1)>0)                ans+=(min(n,a[i])-i-1);        printf("%lld\n",ans*2);    }    return 0;}


B题:

A year after his bacteria experiment, Jason decided to perform another experiment on a new bacteria specie which evolves in a special way. The initial form of the bacteria can be considered as an undirected tree withN nodes in terms of graph theory. Every hour, an edge(x, y) is built if there exists a nodez such that, in the previous hour, there exists edge(x, z) and edge (y, z), but not edge (x, y). The bacteria keep evolving until no more edges can be formed.

The following graph shows a type of bacteria which requires 2 hours to fully evolve:

As it may take months if not years for the bacteria to evolve to its ultimate form, it is impossible for Jason to stay at the laboratory to observe the change of the bacteria throughout the entire process. Therefore, he wants you to calculate the time required for the bacteria to fully evolve, so that he can just get back to the laboratory on time.


Input

The first line contains an integer N. (2 ≤ N ≤ 5 × 105)

The next N - 1 line each contains two integersu and v, which means there exists an edge between nodeu and v. (1 ≤ u, v ≤ N)

The given graph is guaranteed to be a valid tree.

Output

Output an integer, the time (in hours) required for the bacteria to fully evolve.

Example
Input
61 55 35 66 26 4
Output
2

题意:

给出一棵树,每一个小时内:只要任意两个点的相邻点中有一个公共点,那么这两点会连一条线

问:会进行多少个小时这样的连线

题解:

找最长链,从任意一个点开始找到一个离他最远的点,再从这个点开始找到另外一个最远的点,这两个点就是两端

比如说 1  2  3  4  5  是一条链,然后1,3    2,4   3,5   ,然后1可以和5连,看得出,只要首尾连接了得到最终的图, 所以答案为 点数 x <=2^n ,的时候,n即为答案

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<vector>#include<stack>#include<queue>#include<cmath>#include<map>using namespace std;const int maxn=5*1e5+5;typedef pair<int, int> pll;int n,m;int d[maxn];vector<pll> edge[maxn];int bfs(int u){    queue<int> Q;    Q.push(u);    d[u]=0;    int max_d=0,max_u=u;    while(!Q.empty())    {        u=Q.front(); Q.pop();        if(d[u]>max_d)  {max_d=d[u];max_u=u;}        for(int i=0;i<edge[u].size();i++)        {            int v=edge[u][i].first;            if(d[v]==-1)            {                Q.push(v);                d[v]=d[u]+edge[u][i].second;            }        }    }    return max_u;}int main(){    //freopen("in.txt","r",stdin);    while(~scanf("%d",&n))    {        int u,v;        for(int i=1;i<=n;i++)  edge[i].clear();        for(int i=1;i<n;i++)        {            scanf("%d%d",&u,&v);            edge[u].push_back(make_pair(v,1));            edge[v].push_back(make_pair(u,1));        }        memset(d,-1,sizeof(d));        int p=bfs(1);        memset(d,-1,sizeof(d));        int q=bfs(p);        int ans=d[q];        int tmp = 1, cnt = 0;        while(tmp<ans)        {            tmp*=2;            cnt++;        }        printf("%d\n",cnt);    }    return 0;}

C题

签到题

找到两个字符串在主字符串的出现的频率,比较大小即可

#include<iostream>#include<cstdio>#include<cstring>using namespace std;char s[105];int main(){    //freopen("in.txt","r",stdin);    while(~scanf("%s",s))    {        int n = strlen(s);        int tot1 = 0, tot2 = 0;        for(int i=0;i<n;i++)        {            if(s[i] == 'L')            {                if(i+1<n && s[i+1]=='S' && i+2<n && s[i+2]=='C')  tot1++;            }            else if(s[i] == 'P')            {                if(i+1<n && s[i+1]=='C' && i+2<n && s[i+2]=='M' && i+3<n && s[i+3]=='S') tot2++;            }        }        if(tot1>tot2)  puts("LSC");        else if(tot1<tot2)  puts("PCMS");        else puts("Tie");    }    return 0;}

D题:

给出两天,问这两天之间(包括这两天)的天数内:周日,周一到周六,这些星期各出现了多少天

题解:

模拟即可


H题:

题意:

给出两个圆,这两个圆一定有交集,求交集里面任意一个点输出即可

题解:

圆心连线和小圆的交点输出即可,注意圆心重合的情况

#include<math.h>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define LL long longstruct node{    LL x,y,r;}a[5];int main(){    //freopen("in.txt","r",stdin);    while(scanf("%lld%lld%lld",&a[1].x,&a[1].y,&a[1].r)!=EOF)    {        scanf("%lld%lld%lld",&a[2].x,&a[2].y,&a[2].r);        if(a[1].r<a[2].r) swap(a[1],a[2]);        double x1,y1,x2,y2,k,t;        if(a[1].x==a[2].x&&a[1].y==a[2].y)            printf("%0.7lf %0.7lf\n",a[2].x*1.0,a[2].y*1.0);        else if(a[1].x!=a[2].x){            k=(a[2].y-a[1].y)*1.0/(a[2].x-a[1].x);            t=sqrt(a[2].r*a[2].r*1.0/(1+k*k));            x1=t+a[2].x;            y1=t*k+a[2].y;            x2=-t+a[2].x;            y2=-t*k+a[2].y;            int flag=-1;            double t1=(x1-a[1].x)*(x1-a[1].x)+(y1-a[1].y)*(y1-a[1].y);            double t2=(x2-a[1].x)*(x2-a[1].x)+(y2-a[1].y)*(y2-a[1].y);            if(t1<t2) printf("%0.7lf %0.7lf\n",x1,y1);            else      printf("%0.7lf %0.7lf\n",x2,y2);        }        else{            double t1=a[2].y+a[2].r;            double t2=a[2].y-a[2].r;            if(fabs(a[1].y-t1)>fabs(a[1].y-t2))                printf("%0.7lf %0.7lf\n",a[2].x*1.0,(a[2].y-a[2].r)*1.0);            else                printf("%0.7lf %0.7lf\n",a[2].x*1.0,(a[2].y+a[2].r)*1.0);        }    }    return 0;}

I题:

给出一个数组,问,如何翻转一个区间内数字的正负值,使得最终数组的相邻数字之差的绝对值和最小

题解:

翻转一个区间只会影响两端的相邻之差的绝对值


K题:

给出一些点,这些点会覆盖一部分区域,然后问你最少需要再加多少个点才能把剩余的区域全部覆盖

很容易看出考虑四周的四个点就可以了




阅读全文
0 0
原创粉丝点击