1. 程式人生 > 其它 >AcWing周賽44

AcWing周賽44

周賽44

4317. 不同正整數的個數

link:https://www.acwing.com/problem/content/4320/

我直接set

#include <iostream>
#include <set>

using namespace std;
int n;
int a[105];
set<int> p;

int main (){
    cin >> n;
    for (int i = 1; i <= n; i ++){
        cin >> a[i];
        if (a[i] > 0)
            p.insert (a[i]);
    }
    cout << p.size() << endl;
        
}

4318. 最短路徑

link:https://www.acwing.com/problem/content/4321/

情況要考慮周全:

  1. 不能有環 (走過的標記一下)

  2. 不能相鄰 (起點或終點的相鄰塊數目 > 1 或者 其餘任何一點的相鄰塊數目 > 2 )考試的時候沒想到

注意邊界問題(起點座標要設定為地圖大小的一半)

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 205;
typedef pair <int, int> pii;

string s;
bool a[N * 2][N * 2];
int x = N, y = N;
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
vector <pii> v;

int main (){
    cin >> s;
    a[x][y] = true;
    v.push_back ({x, y});
    //判相交
    for (int i = 0; i < s.size(); i ++){
        if (s[i] == 'U')
            x --;
        if (s[i] == 'D')
            x ++;
        if (s[i] == 'L')
            y --;
        if (s[i] == 'R')
            y ++;
        v.push_back ({x, y});
        if (a[x][y]){
            cout << "NO";
            return 0;
        }
        a[x][y] = true;
    }

    int n = v.size();
    bool flag = true;
    //判相鄰:大於二(起點終點:大於一)
    //起點終點
    int cnt0 = 0, cntn = 0;
    for (int i = 0; i < 4; i ++){
        int xx = v[0].first + dx[i], yy = v[0].second + dy[i];
        if (a[xx][yy])
            cnt0 ++;
    }
    for (int i = 0; i < 4; i ++){
        int xx = v[n - 1].first + dx[i], yy = v[n - 1].second + dy[i];
        if (a[xx][yy])
            cntn ++;
    }
    if (cnt0 > 1 || cntn > 1){
        cout << "NO";
        return 0;
    }

    //其餘點
    for (int j = 0; j < v.size(); j ++){
        int cnt = 0;
        for (int i = 0; i < 4; i ++){
            int xx = v[j].first + dx[i], yy = v[j].second + dy[i];
            if (a[xx][yy])
                cnt ++;
        }
        if (cnt > 2){
            cout << "NO";
            return 0;
        }
    }

    cout << "YES";
    
}

4319. 合適數對

link:https://www.acwing.com/problem/content/4322/

算術基本定理

本題就是求所有質因子的個數能被 k 整除

看公式:

\[N = p_1^{\alpha _ 1}p_2^{\alpha _ 2}...p_k^{\alpha _ k}\\ a_i = p_1^{\alpha _ 1}...p_k^{\alpha _k}\\ a_j = p_1^{\beta _ 1}...p_k^{\beta _k}\\ 則需滿足 k | (\alpha _ i + \beta_ i) \]

然後用粗略計算一下,可以發現 $2 * 3 * 5 * 7 * 11 * 13 * 17 = 510510 > 100000 $所以最多隻有六種質因子(最多六項)

統計質因子次數

//大佬的STL做法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010;
LL a[N];
map <vector<PII>, int> cnt;

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    LL ans = 0;
    for (int i = 1; i <= n; i ++) {
        int x = a[i];
        vector <PII> b, c;
        for (int j = 2; j <= x / j; j ++) {
            int c = 0;
            if (x % j == 0) {
                while (x % j == 0) x /= j, ++c;
            }
            if (c % m) b.push_back({j, c % m});
        }
        if (x > 1) b.push_back({x, 1});
        for (auto [x, y] : b) {
            c.push_back({x, m - y});
        }
        ans += 1ll * cnt[c];
        cnt[b]++;
    }
    cout << ans;
    return 0;
}