2019牛客多校第一场

2019牛客多校第一场

A:Equivalent Prefixes(单调栈)

  • 题意:注意是每个子区间都要满足
  • 可以发现必须要有单调性,想到要同增同减
  • 然后找到一个满足同增同减,但是不符合题意的反例:
    • 1 3 2
    • 1 3 0
  • 然后发现必须要维护一个以当前点结尾的最长上升子序列长度相同
  • 如果不同就break
  • 就想到单调栈 不过我不会严格证明,比赛的时候找不到反例
#include <bits/stdc++.h>

#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
const int N = 1e5 + 10;
int a[N], b[N];
int q1[N], q2[N];

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; i++)scanf("%d", &a[i]);
        for (int i = 1; i <= n; i++)scanf("%d", &b[i]);
        int l1 = 0, r1 = 0, l2 = 0, r2 = 0;
        int ans = 1;
        for (int i = 1; i <= n; i++) {
            while (l1 <= r1 && q1[r1] > a[i]) {
                r1--;
            }
            q1[++r1] = a[i];
            while (l2 <= r2 && q2[r2] > b[i]) {
                r2--;
            }
            q2[++r2] = b[i];
            if ((r1 - l1) == (r2 - l2))ans = i;
            else break;
        }
        printf("%d\n", ans);
    }
    return 0;
}

B: Integration(数学)

  • 题意:求那个积分
  • 裂项
    • 把乘换成减,两项两项地换
    • 复杂度
    • 积分的可加性
    • 记录系数,最后再乘以积分的值
  • 代码
#include <bits/stdc++.h>

#define ll long long
using namespace std;
const int mod = 1e9 + 7;
ll s[1010];
ll pre[1010];

ll qpow(ll a, ll n) {
    ll res = 1;
    a %= mod;
    while (n) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) scanf("%lld", &s[i]), pre[i] = 0;
        pre[1] = 1;
        for (int i = 2; i <= n; ++i) {
            for (int j = 1; j < i; ++j) {
                pre[j] = (pre[j] * qpow(((s[i] * s[i] % mod - s[j] * s[j] % mod)%mod + mod) % mod,mod-2)+mod)% mod;
                pre[i] = ((pre[i] - pre[j]) % mod + mod) % mod;
            }
        }
        ll ans = 0;
        for (int i = 1; i <= n; ++i) {
            ans = ((ans + pre[i] * qpow(s[i] * 2LL, mod - 2) % mod+mod)%mod+mod) % mod;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

C:Euclidean Distance(数学+贪心)

#include <bits/stdc++.h>

#define ll long long
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 1e4 + 10;
ll s[maxn];
ll pre[maxn];

int main() {
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &s[i]);
        }
        sort(s + 1, s + 1 + n);
        reverse(s + 1, s + 1 + n);
        pre[0] = -m;
        for (int i = 1; i <= n; ++i) {
            pre[i] = pre[i - 1] + s[i];
        }
        ll pos = n;
        for (ll i = 0; i < n; ++i) {
            if (pre[i] > s[i + 1] * i) {
                pos = i;
                break;
            }
        }
        ll ansa = pre[pos] * pre[pos] * pos;
        ll ansb = pos * pos;
        for (ll i = pos + 1; i <= n; ++i) {
            ansa += s[i] * s[i] * ansb;
        }
        ansb *= (m * m);
        ll g = __gcd(ansa, ansb);
        ansa /= g;
        ansb /= g;
        if (ansb == 1) {
            printf("%lld\n", ansa);
        } else {
            printf("%lld/%lld\n", ansa, ansb);
        }
    }
    return 0;
}

E:ABBA(贪心+DP)

  • 题意:就是有个"AB",个"BA",问能结合成多少个序列.这个要求是AB和BA的顺序不变,即A和B的相对位置不变.我们要讨论一下什么才是合法的状态.

  • 贪心:

    • 假设只有个AB,合法情况是每个B前面要有个A
    • 假设除了有AB,还有个BA,那每个B前面可以有超过个A,但是第一个B前面还是要有个A.否则就会使BA类型的某个B后面没A.
    • B与后面的A可以构成BA,相当于抵消了一个A,那下一个B前面就只需要有未被抵消的A.
    • 所以A-B小于等于是合法的.当A-B等于,意味着最后一个只能是A,因为如果最后一个是B,那B前面就有个未被抵消的A.
    • A前面有多少个B也是同理.
  • DP

    • 代表A的个数,代表B的个数.值代表合法方案.

    • 初始化,按照上述前缀的限定

    • 不考虑那么多,可以简单得出

    • 但是要排除非法的情况

      • 是合法情况
      • 注意的情况
  • 代码
  #include <bits/stdc++.h>

  #define ll long long
  using namespace std;
  const ll mod = 1e9 + 7;
  const ll N = 1e5 + 10;
  ll dp[2010][2010];

  int main() {
      ll n, m;
      while (scanf("%lld%lld", &n, &m) != EOF) {
          ll cnt = (n + m);
          for (int i = 0; i <= cnt; i++)
              for (int j = 0; j <= cnt; j++)
                  dp[i][j] = 0;
          for (ll i = 0; i <= cnt; i++) {
              dp[i][0] = dp[0][i] = 1;
          }
          for (ll i = 1; i <= cnt; i++) {
              for (ll j = 1; j <= cnt; j++) {
                  if (i == j) {
                      if (n)
                          dp[i][j] = (dp[i][j] + dp[i][j - 1]) % mod;
                      if (m)
                          dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
                  } else if (j > i) {
                      if (j - i < m)
                          dp[i][j] = ((dp[i][j] + dp[i - 1][j]) % mod + dp[i][j - 1]) % mod;
                      else if (j - i == m)
                          dp[i][j] = (dp[i][j] + dp[i][j - 1]) % mod;
                  } else if (i > j) {
                      if (i - j < n)
                          dp[i][j] = ((dp[i][j] + dp[i - 1][j]) % mod + dp[i][j - 1]) % mod;
                      if (i - j == n)
                          dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
                  }
                  //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
              }
          }
          printf("%lld\n", dp[cnt][cnt] % mod);
      }

      return 0;

F:Random Point in Triangle(期望+随机+叉积)

参考了一下大牛的博客

https://www.cnblogs.com/WAautomaton/p/11211864.html

首先我们得出当一个点P随机落在三角形内部,新三角形BPC的高的期望为
证明如下:(字丑勿怪)
图片说明
得到了这个,那就好办了,就变成了简单几何问题.
剩下的可以看大佬的博客,我就不赘述了.

#include <bits/stdc++.h>

#define ll long long
using namespace std;
const ll mod = 1e9 + 7;
const ll N = 1e5 + 10;

int main() {
    ll x1, y1, x2, y2, x3, y3;
    while (~scanf("%lld%lld%lld%lld%lld%lld", &x1, &y1, &x2, &y2, &x3, &y3)) {
        ll ans = 11;
        ll cnt = abs(x1 * y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2);
        ans = ans * cnt;
        printf("%lld\n", ans);
    }
    return 0;
}

Fraction Comparision(大数+JAVA)

居然不会JAVA的多组输入,JAVA白考98了…..

一开始用了nextline 一直RE.

import java.math.*;
import java.util.*;
public class Main {
    static BigInteger ans,m;
    static BigInteger[] arr;
    static int n;
    public static void main(String []args){

      Scanner cin = new Scanner(System.in);
      //Long x,a,y,b;
      BigInteger x,a,y,b;
      while(cin.hasNextBigInteger()){
          x=cin.nextBigInteger();
          a=cin.nextBigInteger();
          y=cin.nextBigInteger();
          b=cin.nextBigInteger();
          int s=b.multiply(x).compareTo(a.multiply(y));
          if(s>0){
              System.out.println(">");
          }else if(s==0){
              System.out.println("=");
          }else{
              System.out.println("<");
          }
      }
    }

}
全部评论

相关推荐

从大一开始就开始学习Java,一路走来真的不算容易,每次面试都被压力,不过这次终于达成了自己的一大心愿!时间线和面经:8.17-投递9.1-一面实习+项目拷打看门狗机制讲一下redis加锁解锁的本身操作是什么Lua脚本是干什么的udp和tcp讲一下流量控制讲一下令牌桶算法说一下大端和小端是什么线程和协程有什么区别怎么切换协程切换的时候具体做了什么对于程序来说,你刚才提到的保存和恢复现场,这个现场有哪些信息udp优势现在有一个客户端和服务端,要实现TCP的通信,我们的代码要怎么写服务器怎么感知有新的连接怎么处理多个客户端的请求连接TCP怎么处理粘包和分包现在有两个文件,然后每个文件都有一亿条URL,每个的长度都很长,要怎么快速查找这两个文件共有的URLHashmap底层说一下怎么尽量提升插入和查询的效率如果要查找快,查询快,还有解决非空的问题,怎么做LoadingCache了解吗手撕:堆排序9.4-二面部门的leader,超级压力面拷打实习+项目,被喷完全没东西类的加载到垃圾回收整个底层原理讲一遍类加载谁来执行类加载器是什么东西,和进程的关系Java虚拟机是什么东西,和进程的关系如果我们要执行hello&nbsp;world,那虚拟机干了什么呢谁把字节码翻译成机器码,操作时机是什么Java虚拟机是一个执行单元吗Java虚拟机和操作系统的关系到底什么,假如我是个完全不懂技术的人,举例说明让我明白一个操作系统有两个Java程序的话,有几个虚拟机有没有单独的JVM进程存在启动一个hello&nbsp;world编译的时候,有几个进程JVM什么时候启动比如执行一条Java命令的时候对应一个进程,然后这个JVM虚拟机到底是不是在这个进程里面,还是说要先启动一个JVM虚拟机的进程垃圾回收机制的时机能手动触发垃圾回收吗垃圾回收会抢占业务代码的CPU吗垃圾回收算法简单说说垃圾回收机制的stop&nbsp;the&nbsp;world存在于哪些时机垃圾回收中的计算Region的时候怎么和业务代码并行执行假如只有一个线程,怎么实现并行Java为什么要这么实现Java效率比C++慢很多,那为什么还要这样实现Java虚拟机到底是什么形式存在的说一下Java和C++的区别还有你对Java设计理念的理解无手撕面试结束的时候,我真的汗流浃背了,面试官还和我道歉,说他是故意压力面想看看我的反应的,还对我给予了高度评价:我当面试官这么多年,你是我见过最好的一个9.9-三面临时通知的加面,就问了三十分钟项目9.11-hr面问过往经历,未来计划,想从腾讯实习中得到什么?当场告知leader十分满意我,所以直接ochr面完一分钟官网流程变成录用评估中,30分钟后mt加微信告知offer正在审批9.15-offer这一次腾讯面试体验真的不错,每个面试官能感觉到专业能力很强,反馈很足,比起隔壁某节真是好太多以后就是鹅孝子了
三本咋了:当面试官这么多年你是我见过的最好的一个
你面试被问到过哪些不会的...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务