牛客寒假算法训练营2

牛客寒假算法训练营2

C.算概率

链接:https://ac.nowcoder.com/acm/contest/3003/C
来源:牛客网

牛牛刚刚考完了期末,尽管 牛牛 做答了所有 n 道题目,但他不知道有多少题是正确的。
不过,牛牛 知道第 i道题的正确率是 pi​。
牛牛 想知道这 n 题里恰好有 0,1,…,n 题正确的概率分别是多少,对 10^9+7 取模。对 10^9 + 7取模的含义是:对于一个 b≠0 的不可约分数 a/b,存在 q 使得 b×q mod (109+7)=a,q 即为 a/b 对 10^9+7取模的结果。

​ 这里其实就是逆元,在考虑的时候,被分数的模数有点吓到了,不知道从何下手,以及如何转换,其实直接用就可以了。。。。也算是涨了一波见识,顺便温习了一下逆元的知识。

由费马小定理我们知道,a mod p如果P为质数,而且a不为p的倍数,那么有 a^(p-1) = 1(mod p),所以a^(p - 2) = 1 / a(mod p),即a的逆元,用于除法的模运算

​ 这道题,给出的概率就直接用就行,不用去考虑什么转化,只要注意取模就好

#include <cstdio>
#include <algorithm>
using namespace std;
#define ll long long
const int base = 1e9 + 7;
ll p[2003];
ll ans[2003][2003];
int n;

void input(){
   
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
   
        scanf("%lld",&p[i]);
    }
}

void work(){
   
    ans[0][0] = 1;
    for(int i = 1;i <= n;i++){
   
        ans[i][0] = ans[i - 1][0] * (base + 1 - p[i]) % base;
    }
    for(int i = 1;i <= n;i++){
   
        for(int j = 1; j <= i;j++){
   
            ans[i][j] = (ans[i - 1][j] * (base + 1 - p[i]) + ans[i - 1][j - 1] * p[i]) % base;
        }
    }
    for(int i = 0;i <= n;i++){
   
        printf("%lld ",ans[n][i]);
    }
}

int main(){
   
    input();
    work();
    return 0;
}


D-数三角

链接:https://ac.nowcoder.com/acm/contest/3003/D
来源:牛客网

牛牛得到了一个平面,这个平面上有 n 个不重合的点,第 i 个点的坐标为 (xi,yi)。

牛牛想知道,这 n 个点形成的三角形中,总共有多少个钝角三角形

​ 高中的知识又全部倒给老师了。。。怎么判断钝角都给忘了。。。。,题目本身感觉也不是特别难的样子,自己做的时候又是判断长度,判断距离的,给搞得太复杂了。。。

#include <cstdio>
#include <utility>
#include <vector>
#include <math.h>
using namespace std;
const int maxn = 503;
int x[maxn];
int y[maxn];
int n;
void input(){
   
    scanf("%d",&n);
    int a,b;
    for(int i = 0;i < n;i++){
   
        scanf("%d%d",&x[i],&y[i]);
    }
}

bool check(int a,int b,int c){
   
    if((x[a] - x[b]) * (x[c] - x[b]) + (y[a] - y[b]) * (y[c] - y[b]) < 0){
   
        if((x[a] - x[b]) * (y[c] - y[b]) - (x[c] - x[b]) * (y[a] - y[b]) != 0){
   
            return true;
        }
    }
    return false;
}

void work(){
   
    int ans = 0;
    for(int i = 0;i < n - 2;i++){
   
        for(int j = i + 1;j < n - 1;j++){
   
            for(int k = j + 1;k < n;k++){
   
                if(check(i,j,k) || check(k,i,j) || check(j,k,i)){
   
                    ans++;
                }
            }
        }
    }
    printf("%d\n",ans);

}

int main(){
   
    input();
    work();
    return 0;
}

F-拿物品

链接:https://ac.nowcoder.com/acm/contest/3003/F
来源:牛客网

牛牛和 牛可乐 面前有 n 个物品,这些物品编号为 1,2,…,n每个物品有两个属性 ai,bi。

牛牛与 牛可乐会轮流从剩下物品中任意拿走一个, 牛牛先选取。

设 牛牛选取的物品编号集合为 H,牛可乐选取的物品编号的集合为 T,取完之后,牛牛 得分为 ∑i∈H;而 牛可乐得分为 ∑i∈Tbii。

牛牛和 牛可乐都希望自己的得分尽量比对方大(即最大化自己与对方得分的差)。

你需要求出两人都使用最优策略的情况下,最终分别会选择哪些物品,若有多种答案或输出顺序,输出任意一种。

​ 每一个物品对于自己的而言的战略价值就等于 a + b,所以双方每一次选取战略价值最高的对自己最有利。其实就是贪心啦。。。

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define ll long long
const int maxn = 2e5 + 7;
int n;
struct node{
   
    ll a;
    int num;
};
node res[maxn];
bool cmp(node a,node b){
   
    return a.a > b.a;
}

void input(){
   
    scanf("%d",&n);
    for(int i = 0;i < n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值