2020牛客寒假算法基础集训营1总结

A题,找符合条件的三角形,脑抽想少了。
符合条件的三角形有许多种:
1.底为1,高为2,底与x轴平行
2.底为1,高为2,底与y轴平行
3.底为2,高为1,底与x轴平行
4.底为2,高为1,底与y轴平行
每种的计算只需要枚举高所经过的顶点即可,但是在边界处的直角三角形会计算重复,需要减去。还应注意:中间部分三角形的方向可以翻转,*2.

#include <iostream>
#include <algorithm>
using namespace std;
const int mod = 1e9 + 7;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    long long n, m;
    cin >> n >> m;
    long long sum = 0;
    long long a,b;
    a = (n-1)*(m-2) % mod;
    a *= (n+m-2);
    a %= mod;
    b = (n-2)*(m-1) % mod;
    b *= (n+m-2);
    b %= mod;
    sum = a+b % mod;
    cout << 2*sum % mod << endl;
    return 0;
}

B题水题,跳过
C题,可以算是个模拟加贪心
挡板只能放在x轴或者y轴之上,所以,只需要计算起点与所有靶子的横纵截距即可

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 50;
double x[maxn],y[maxn];
int numx = 0, numy = 0;
int main()
{
    double x0,y0;
    cin >> x0 >> y0;
    int n, k;
    cin >> n >> k;
    for(int i = 0; i < n; i++)
    {
        long long x1,y1;
        cin >> x1 >> y1;
        if(x1*x0<0)
        {
            y[numy++] = y0-(1.0 *x0*(y0-y1))/(x0-x1);
        }
        if(y1*y0<0)
        {
            x[numx++]= x0-(1.0 *y0*(x0-x1))/(y0-y1);
        }
    }
     
    if(n-numx>k&&n-numy>k)
    {
        cout << -1 << endl;
        return 0;
    }
     
    sort(x,x+numx);
    sort(y,y+numy);
    int cnt = n - k;
    double ans = 6000000009;
 
//  cout << num << endl;
     
    for(int i = 0; i + cnt - 1 < numx; i++)
    {
        ans = min(ans, x[i+cnt-1] - x[i]);
    //  cout << ans << endl;
    }
    //cout << ans << endl;
    for(int i = 0; i + cnt - 1 < numy; i++)
    {
        ans = min(ans, y[i+cnt-1] - y[i]);
    }
    printf("%.9lf\n",ans);
    return 0;
}

D题更加水了…
E题我使用的是算数基本定理(唯一分解定理)
根据对x的质因数分解来计算x的因数个数,按题意直接迭代即可。

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1e6 + 50;
int su[N] = {0};
long long zhi[N];
int z = 0;
int aishai()
{
    su[1] = 1;
    for(int i = 2; i <= 1e6 + 5; i++)
    {
        if(su[i] == 0)
        {
            zhi[z] = i;
            z++;
            for(int j = 2; j * i <= 1e6 + 5; j++)
            {
                su[i*j] = 1;
            }
        }
    }
     
}
long long hanshu(long long a)
{
        long long ans = 1;
        long long n = a;
        for(int i = 0; i < z && zhi[i] <= a; i++)
        {
            if(a % zhi[i] == 0)
            {
                long long cnt = 0;
                while(a % zhi[i] == 0)
                {
                    a /= zhi[i];
                    cnt++;
                }
                ans *= (1 + cnt);
            }
        }
        if(a > 1)
        ans *= 2;
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    aishai();
    long long n;
    cin >> n;
    long long ans = 1,t;
    while( (t = hanshu(n)) != 2)
    {
        ans++;
        n = t;
    }
    cout << ans << endl;
    return 0;
}

G题,暴力
记录每一种字母出现的位置,之后遍历所有字母,每次只取k个字母的间距,记录最小值即可。

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2e5 + 50;
int a[27][maxn],b[27];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    for(int i = 0; i < n; i++)
    {
        a[s[i]-'a'][b[s[i]-'a']++] = i;
    }
    int ans = maxn;
    for(int i = 0; i <= 'z' - 'a'; i++)//遍历所有字母
    {
        for(int j = 0; j+k <= b[i]; j++)
        {
            ans = min(ans, a[i][j+k-1] - a[i][j] + 1);
        }
    }
    if(ans == maxn)
    cout << -1 << endl;
    else
    cout << ans << endl;
    return 0;
}

H题套的尺取法模板,学会之后,一定滚回来更新代码。

发布了11 篇原创文章 · 获赞 0 · 访问量 626

猜你喜欢

转载自blog.csdn.net/weixin_43934344/article/details/104240654
今日推荐