[BestCoder #31]简要题解

42 篇文章 0 订阅
15 篇文章 0 订阅

zhw神犇出题就是强啊。。。

A:pairs

John 在 X 轴上拥有n个点,他们的坐标分别为 (x[i],0) , (i=0,1,2,,n1) 。 他想知道有多少对 <a,b> <script id="MathJax-Element-319" type="math/tex"> </script>满足 |x[b]x[a]|k(a<b)
题解
对于每个点,二分它右边离他最远、但是又在距离 k 内的点,然后加到答案里,这样做复杂度是nlogn的,由于pretest太水,最终AC的人竟然并不是很多

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 110000

using namespace std;

typedef long long int LL;

LL ans=0;
int x[MAXN],n,k;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans=0;
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%d",&x[i]);
        sort(x+1,x+n+1);
        for(int i=1;i<=n;i++)
        {
            int lowerBound=i,upperBound=n;
            int tmp;
            while(lowerBound<=upperBound)
            {
                int mid=(lowerBound+upperBound)>>1;
                if(x[mid]-x[i]>k) upperBound=mid-1;
                else tmp=mid,lowerBound=mid+1;
            }
            ans+=(LL)(tmp-i);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

B:beautiful number

A=ni=1ai10ni(1ai9) ( n A的位数)。若 A 为“漂亮的数”当且仅当对于任意1i<n满足 a[i]a[i+1] 且对于任意 1in,i<jn ,满足 a[i] mod a[j]=0 (例如931是一个“漂亮的数”而87不是),求在区间 [L,R] (包含L和R)里“漂亮的数”的个数。
题解
此题做法很多,可以暴力从1枚举到1e9,然后打表记下来,也可以记录下前面一位数字往后面一位数字如何转移,然后做一个DFS的预处理,也可以直接用DFS在线回答询问
我的方法是最后一种,代码比较直白,就不需要过多解释了吧
坑爹的是此题pretest依然很水,然后我保存数字每个数位的digit数组只开了10位,但是如果到极限数据(1e9)时就需要11位,然后导致我最终fst了,坑爹啊!!!!(zhw的pretest实在太神奇了)

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

using namespace std;

int digit[11],len; //digit数组保存数位(个位在1),len数组保存x的长度,digit数组刚开始我开成10然后过了pretest最终fst有木有!!!!掉rating有木有!!!!!
int num[10][11]={
    {10,0,1,2,3,4,5,6,7,8,9},
    {1,1,0,0,0,0,0,0,0,0,0},
    {2,2,1,0,0,0,0,0,0,0,0},
    {2,3,1,0,0,0,0,0,0,0,0},
    {3,4,2,1,0,0,0,0,0,0,0},
    {2,5,1,0,0,0,0,0,0,0,0},
    {4,6,3,2,1,0,0,0,0,0,0},
    {2,7,1,0,0,0,0,0,0,0,0},
    {4,8,4,2,1,0,0,0,0,0,0},
    {3,9,3,1,0,0,0,0,0,0,0}
};

int ans=0;

void DFS(int last,int pos,bool danger)
{
    if(pos==0)
    {
        ans++;
        return;
    }
    for(int i=1;i<=num[last][0];i++)
    {
        int next=num[last][i]; //下一个填入的数字是next
        if(!danger)
        {
            if(next!=0&&last!=0)
                DFS(next,pos-1,false);
            else if(!last)
                DFS(next,pos-1,false);
        }
        else if(last==digit[pos+1]&&digit[pos]>=next)
        {
            if(digit[pos]==next)
                DFS(next,pos-1,true);
            else
                DFS(next,pos-1,false);
        }
    }
}

int work(int x) //求[1,x]中美丽的数的个数
{
    if(!x) return 1;
    ans=0;
    len=0;
    while(x)
    {
        digit[++len]=x%10;
        x/=10;
    }
    for(int i=0;i<=9;i++)
        if(digit[len]>=i)
        {
            if(digit[len]==i)
                DFS(i,len-1,true);
            else
                DFS(i,len-1,false);
        }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int L,R;
        scanf("%d%d",&L,&R);
        printf("%d\n",work(R)-work(L-1));
    }
    return 0;
}

C:chess

在n∗n的国际象棋中,放置若干个国王和k个车,使得国王之间不互相攻击,车之间不互相攻击,车不可攻击到国王(这并不代表国王不能攻击到车)。国王能攻击到它上下左右,左上左下右上右下八个位置的棋子,车可以攻击到同一行或同一列中的棋子,求方案总数对1000000007取模后的值。

D:numbers

现在你有一个栈和 n 个数1,2,3,,n。这 n 个数依次进入栈顶,且在某个时刻在栈顶中弹出。你可以参见样例获得更多的信息。
这个问题非常简单,因此我想给你一些限制条件。
这里有m个限制,每个限制形如 <A,B> <script id="MathJax-Element-21" type="math/tex"> </script>,表示 A 必须在B之前先弹出。
你能告诉我有多少种合法的弹出栈的方案吗?
我知道这个答案或许非常大,你只需告诉我这个答案 mod1000000007(109+7) 就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值