La Salle-Pui Ching Programming Challenge 2017 Gym - 101522A,B,C,D,H,I,K

A题:

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

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define LL long long
int 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 with N nodes in terms of graph theory. Every hour, an edge (x, y) is built if there exists a node z 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 integers u and v, which means there exists an edge between node u 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
6
1 5
5 3
5 6
6 2
6 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 long
struct 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值