Codeforces Round #Pi (Div. 2)

题目地址

A. Lineland Mail

题目大意:升序给出n个数,输出每个数与其他数相差的最小值最大值

解题思路:每个数的最小数为该数与相邻2个数的最小差值,最大数为该数与第一个数和最后一个数的最大差值,注意第一个数和最后一个数的处理

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <queue>
#include <vector>

using namespace std;

const int maxn = 100000+10;

int a[maxn];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i = 0; i < n-1; i++)
    {
        int minn = a[i+1] -a[i];
        if(i>0)
            minn = min(minn,a[i] -a[i-1]);
        int maxx = a[n-1]-a[i];
        maxx = max(maxx,a[i]-a[0]);
        printf("%d %d\n",minn,maxx);
    }
    printf("%d %d\n",a[n-1]-a[n-2],a[n-1]-a[0]);
    return 0;
}

B. Berland National Library

题目大意:给出n个人进出图书馆的情况,若为‘+ x’表示编号为x的人进入图书馆,若为‘- x’表示编号为x的人从图书馆出去,根据给出数据求图书馆可以容纳的最少人数

解题思路:用2个变量cur记录当前图书馆的人数,cnt记录图书馆可容纳的最小人数,模拟进出的情况,若当前有人进入图书馆,cur++,但只有当cur<cnt时,cnt才需要++;若当前有人从图书馆出去,看当时的cur是否为0,cur不为0时考虑出去的那个人是不是从输入数据里面进入的

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>
#include <set>

using namespace std;

const int maxn = 1e6+10;
int in[maxn];

int main()
{
    int n;
    scanf("%d",&n);
    getchar();
    int cnt = 0;
    int cur = 0;
    memset(in,0,sizeof(in));
    while(n--)
    {
        int x;
        char s[10];
        scanf("%s%d",s,&x);
        if(s[0] == '+')
        {
            cur++;
            if(!in[x])
                in[x] = 1;
            if(cur > cnt)
                cnt++;
        }
        else if(s[0] == '-')
        {
            if(cur == 0)
            {
                in[x] == 0;
                cnt++;
            }
            else
            {
                 if(in[x])//原来就在
                 {
                     in[x] = 0;
                     cur--;
                 }
                else
                    cnt++;
            }
        }
    }
    printf("%d\n",cnt);
    return 0;
}

C. Geometric Progression

题目大意:给出n,k及n个数,在n个数中按给出顺序选择3个数,使这3个数构成公比为k的等比数列,注意3个等比数的顺序为输入的顺序,不一定相邻,但要严格下标序号递增,求这3个数有多少种选择

解题思路:用2个mpl记录第i个数左边的情况,mpr记录第i个数左边的情况,枚举每个数是否在左边存在a[i]/k,右边存在a[i]*k,将所有情况累加即为答案

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>
#include <set>

using namespace std;

const int maxn = 2e5+10;
long long a[maxn];

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    map<long long,int> mpl,mpr;
    for(int i = 1; i <= n; i++)
    {
        scanf("%I64d",&a[i]);
    }
    for(int i = n; i >= 2; i--)
        mpr[a[i]]++;
    mpl[a[1]]++;
    long long res = 0;
    for(int i = 2; i <= n; i++)
    {
        mpr[a[i]]--;
        if(a[i]%k==0 && mpl[a[i]/k] && mpr[a[i]*k])
            res += (long long)mpl[a[i]/k]*mpr[a[i]*k];
        mpl[a[i]]++;
    }
    printf("%I64d\n",res);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值