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 · 訪問量 1737
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章