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 )考试的时候没想到

    image-20220326223519896

注意边界问题(起点坐标要设置为地图大小的一半)

#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;
}
posted @ 2022-03-27 15:48  Sakana~  阅读(26)  评论(0编辑  收藏  举报