20191011模拟赛

Posted beyondlimits

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20191011模拟赛相关的知识,希望对你有一定的参考价值。

T1

题目大意

给定一个长方体的体积(v),确定其长宽高(a,b,c)使得其长方体的表面积最小。

思路

根据均值不等式:

(a+b+c geq 3 imes^3 sqrt{abc})

代入(2ab, 2bc, 2ac),即可得到(ab+bc+ac geq 6 imes^3 sqrt{v^2}),当且仅当(a=b=c)时成立。

我们发现这个右边的式子不能直接进行计算,考虑牛顿迭代或暴力枚举。

但是(a=b=c)这个条件不一定能满足,因为题目限制(a,b,c in mathbb{Z})。所以我们应该使(a,b,c)三者尽量靠近。

故可以通过枚举(a,b),表达出(c),统计即可。

复杂度为(O(V^{frac{2}{3}}))

代码

#include <bits/stdc++.h>
const int INF = 2147483646;
typedef int intt;
#define int long long
using namespace std;
int v, res, ans = INF;
int calc(int a, int b, int c) { return ((a * b) << 1) + ((b * c) << 1) + ((a * c) << 1); }
intt main() {
    cin >> v;
    for(int i = 1; i * i * i <= v; i++) {
        if(v % i != 0)
            continue;
        res = calc(i, sqrt(v / i), sqrt(v / i));
        if(res > ans)
            continue;
        for(int j = 1; j * j <= (v / i); j++) {
            if((v / i) % j != 0)
                continue;
            ans = min(ans, calc(i, j, (v / i) / j));
        }
    }
    cout << ans << endl;
    return 0;
}

牛顿迭代版:

#include <bits/stdc++.h>
const int lim = 100;
typedef long long ll;
using namespace std;
long double x, v;
int main() {
    cin >> v;
    v *= v;
    x = 10;
    for(int i = 1; i <= lim; i++)
        x = x - (x * x * x - v) / (3 * x * x);
    cout << 6 * x << endl;
    return 0;
}

T2

题目大意

给定一个字符串,计算出所有互不相交的回文子串对的个数。

思路

(90pts:)处理出所有的回文子串的(l,r),然后按左端点,右端点排序,枚举每个区间,二分出第一个互不相交的区间,累加其及其之后的答案即可。复杂度为(O(n^3 + p imes logn)),其中(p)为回文区间总数。(ps:(n^3)是指我之前的回文序列的判断与统计,十分暴力...)

(100pts:)首先优化回文序列的寻找过程。枚举每一个点,然后递归扩展左右,然后使用树状数组维护前缀和,最后枚举查询,查询到是区间右端点比当前区间左端点小的个数,累加即可。

代码

(90pts:)

#include <bits/stdc++.h>
const int MAXN = 2050;
using namespace std;
char s[MAXN];
int len, num, ans;
struct node {
    int l, r;
    bool operator < (const node &a) const {
        return a.l == l ? a.r > r : a.l > l;
    }
}a[200000000];
bool check(int x, int y) {
    for(int i = x, j = y; i <= j; i++, j--) {
        if(s[i] != s[j])
            return false;
    }
    return true;
}
bool check1(int x, int y) { return a[x].l > a[y].r; }
int main() {
    cin >> s + 1;
    len = strlen(s + 1);
    for(int i = 1; i <= len; i++) {
        for(int j = i; j <= len; j++) {
            if(check(i, j))
                a[++num] = (node){i, j};
        }
    }
    sort(a + 1, a + num + 1);
    for(int i = 1; i <= num; i++) {
        int l = i + 1, r = num, res = 0;
        while(l <= r) {
            int mid = (l + r) >> 1;
            if(check1(mid, i)) {
                res = mid;
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        if(res != 0)
            ans += (num - res + 1);
    }
    cout << ans << endl;
    return 0;
}

(100pts:)

#include <bits/stdc++.h>
const int MAXN = 2050;
typedef int intt;
#define int long long
using namespace std;
char s[MAXN];
int len, num, ans, c[MAXN];
struct node {
    int l, r;
}a[20000000];
int lowbit(int x) { return x & (-x); }
void add(int x) {
    while(x <= len) {
        c[x]++;
        x += lowbit(x);
    }
}
int query(int x) {
    int res = 0;
    while(x > 0) {
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}
void solve(int l, int r) {
    if(l == 0 || r == len + 1)
        return ;
    a[++num] = (node){l, r};
    add(r);
    if(s[l - 1] == s[r + 1])
        solve(l - 1, r + 1);
}
intt main() {
    cin >> s + 1;
    len = strlen(s + 1);
    for(int i = 1; i <= len; i++) {
        solve(i, i);
        if(s[i] == s[i + 1])
            solve(i, i + 1);
    }
    for(int i = 1; i <= num; i++)
        ans += query(a[i].l - 1);
    cout << ans << endl;
    return 0;
}

T3

题目大意

给定两个升序序列(A,B),当(A[i]-x leq B[j] leq A[i]+y)时则可以将(A[i])(B[j])匹配。求最大匹配数。

思路

(50pts:)(dp),设(f[i][j])表示(A)中前(i)个数和(B)中前(j)个数的最大匹配数。直接简单的转移即可,复杂度为(O(n^2))

(100pts:)由于升序,且区间长度一定,则可以进行贪心的选取,即尽可能让每一个点和一个右端点尽量靠左的区间进行匹配,尽可能最大的利用区间,让剩下的点有更多的机会去匹配。实现只需要用两个指针即可。复杂度为(O(n))

代码

(50pts:)

#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
const int MAXN = 1050;
using namespace std;
int n, m, x, y, a[MAXN], b[MAXN], f[MAXN][MAXN];
int main() {
    cin >> n >> m >> x >> y;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    for(int i = 1; i <= m; i++)
        cin >> b[i];
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            if(a[i] - x <= b[j] && a[i] + y >= b[j])
                f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
            else
                f[i][j] = max(f[i - 1][j - 1], max(f[i - 1][j], f[i][j - 1]));
        }
    }
    cout << f[n][m] << endl;
    return 0;
}

(100pts:)

#include <bits/stdc++.h>
const int MAXN = 100050;
using namespace std;
struct node {
    int x, y;
}g[MAXN];
int n, m, x, y, c, p1 = 1, p2 = 1, ans, f[MAXN];
bool flag;
int main() {
    cin >> n >> m >> x >> y;
    for(int i = 1; i <= n; i++) {
        cin >> c;
        g[i].x = c - x;
        g[i].y = c + y;
    }
    for(int i = 1; i <= m; i++)
        cin >> f[i];
    while(p1 <= n && p2 <= m) {
        if(f[p2] >= g[p1].x && f[p2] <= g[p1].y) {
            ans++;
            p1++;
            p2++;
        }
        else if(f[p2] > g[p1].y)
            p1++;
        else if(f[p2] < g[p1].x)
            p2++; 
    }
    cout << ans << endl;
    return 0;
}

以上是关于20191011模拟赛的主要内容,如果未能解决你的问题,请参考以下文章

[20191011]通过bash计算sql语句的sql_id.txt

20191011-构建我们公司自己的自动化接口测试框架-TestData的数据准备

iOS Swift 中的 Android 片段模拟

php 在终端中模拟一点加载字符的片段

当我想模拟数据并测试 UI 片段时,doNothing() 不起作用

google-map 片段应用程序在模拟器中崩溃后打开 WebView 活动