超级码力在线编程大赛初赛 第二场

1.三角魔法

判断一个点在不在三角形内,有多种方法,这里采用面积法,即整个三角形的面积=3个小三角形面积之和。采用海伦公式计算面积。

class Solution {
public:
    /**
     * @param triangle: Coordinates of three points
     * @param point: Xiaoqi's coordinates
     * @return: Judge whether you can cast magic
     */
     struct node
{
    double x;
    double y;
};
float TriangleArea(node a,node b,node c)
{
    double AB,BC,AC,P;
    AB=sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
    AC=sqrt((c.x-a.x)*(c.x-a.x)+(c.y-a.y)*(c.y-a.y));
    BC=sqrt((c.x-b.x)*(c.x-b.x)+(c.y-b.y)*(c.y-b.y));
    P=(AB+AC+BC)/2;
    return sqrt(P*(P-AB)*(P-AC)*(P-BC));
}
bool IsinTrangle(node a,node b,node c,node d)
{
    float s1,s2,s3,sum;
    s1=TriangleArea(a,b,d);
    s2=TriangleArea(a,c,d);
    s3=TriangleArea(b,c,d);
    sum=TriangleArea(a,b,c);
    if(0.0000001>fabs(sum-s1-s2-s3))
    return true;
    else
    return false;
}
    string castMagic(vector<vector<int>> &triangle, vector<int> &point) {
        // write your code here
        node a,b,c,d;
        a.x=triangle[0][0];
        a.y=triangle[0][1];
        b.x=triangle[1][0];
        b.y=triangle[1][1];
        c.x=triangle[2][0];
        c.y=triangle[2][1];
        d.x=point[0];
        d.y=point[1];
        if(IsinTrangle(a,b,c,d))
        return "Yes";
        else
        return "No";
    }
};

2.区间异或

求区间最大值最小值,可以用ST算法,然后异或一下即可。刚开始用线段树TLE了QAQ

class Solution {
public:
    /**
     * @param num: array of num
     * @param ask: Interval pairs
     * @return: return the sum of xor
     */
    int Intervalxor(vector<int> &num, vector<vector<int>> &ask) {
        // write your code here
        int log[50005];
        int f1[50005][25];
        int f2[50005][25];
        int n=num.size();
        log[0]=-1;
        for(int i=1;i<=n;++i)
        {
            f1[i][0]=num[i-1];
            f2[i][0]=num[i-1];
            log[i]=log[i>>1]+1;
        }
        for(int j=1;j<=20;++j)
        for(int i=1;i+(1<<j)-1<=n;++i)
        {
            f1[i][j]=max(f1[i][j-1],f1[i+(1<<j-1)][j-1]);
            f2[i][j]=min(f2[i][j-1],f2[i+(1<<j-1)][j-1]);
        }
    int ans=0;
    for(int i=0;i<ask.size();++i)
    {
        vector<int>cur=ask[i];
        int l1=cur[0],r1=cur[1];
        int l2=cur[2],r2=cur[3];
        int s1=log[r1-l1+1];
        int s2=log[r2-l2+1];
        ans^=(max(f1[l1][s1],f1[r1-(1<<s1)+1][s1])+min(f2[l2][s2],f2[r2-(1<<s2)+1][s2]));
    }
    return ans;
    }
};

3.五字回文

枚举中间的数,向外扩,判断是否是abcba即可。

class Solution {
public:
    /**
     * @param s: The given string
     * @return: return the number of Five-character palindrome
     */
    int Fivecharacterpalindrome(string &s) {
        // write your code here
    int len=s.size();
    int ans=0;
    for(int i=2;i<len-2;++i)
    {
        int a=i-2;
        int b=i-1;
        int c=i+1;
        int d=i+2;
        if(s[a]==s[d]&&s[b]==s[c]&&s[i]!=s[a]&&s[i]!=s[b]&&s[a]!=s[b])
        ans++;
    }
    return ans;
    }
};

4.小栖的金字塔

我们发现从(k,k)到(n,n)的方案数可以转化为(1,1)到(n-k+1,n-k+1)的方案数。然后就是玄学的超级卡特兰数了。我们发现。
Fn*(n+1)=(6*n-3)*Fn-1-(n-2)*Fn-2
方案数就是超级卡特兰数X2。因为左边乘了n+1,要除下去,所以要用到除法取模。

class Solution {
public:
    /**
     * @param n: The number of pyramid levels n
     * @param k: Possible coordinates k
     * @return: Find the sum of the number of plans
     */
long long mod=1e9+7;
long long f[10000007];
long long quickpow(long long a,long long b)
{
    long long res=1;
    while(b)
    {
        if(b&1)
        res=res*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}
long long cal(int a,int n)
{
    if(a==n)
    return 1;
    return f[n-a]*2%mod;
}
    int pyramid(int n, vector<int> &k) {
        // write your code here
    f[0]=1;
    f[1]=1;
    for(int i=2;i<=n;++i)
    f[i]=((6*i-3)*f[i-1]%mod-(i-2)*f[i-2]%mod+mod)%mod*quickpow(i+1,mod-2)%mod;
    int x;
    long long ans=0;
    for(int i=0;i<k.size();++i)
    {
        x=k[i];
        ans=(ans+cal(x,n))%mod;
    }
    return ans;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值