E. Ehab's REAL Number Theory Problem (bfs + 思维)

题目:传送门

题意:

思路: 图文博客

#include <bits/stdc++.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

const int N = 1e5 + 5, M = 1e3 + 5;

int pre[N], tot, depth[N * 10];
bool vis[N];
vector < pair<int, int> > G[N * 10];

void init() {
    rep(i, 2, M - 5) {
        if(!vis[i]) pre[++tot] = i;
        rep(j, 1, tot) {
            if(i * pre[j] > M - 5) break;
            vis[i * pre[j]] = 1;
            if(i % pre[j] == 0) break;
        }
    }
}

pair < int, int > tmp;

queue < int > Q;

int bfs(int x) {
    mem(vis, 0);
    mem(depth, 0);

    depth[x] = 1;

    while(!Q.empty()) Q.pop();

    Q.push(x);

    while(!Q.empty()) {
        int pos = Q.front(); Q.pop();
        for(auto v : G[pos]) {
            if(vis[v.second]) continue;
            vis[v.second] = 1;
            if(depth[v.first]) return depth[pos] + depth[v.first] - 1;
            depth[v.first] = depth[pos] + 1;
            Q.push(v.first);
        }
    }

    return INF;

}

int main() {

    init();

    int n;
    scanf("%d", &n);

    int ans = INF;

    rep(i, 1, n) {
        int x; scanf("%d", &x);
        tmp = make(0, 0);
        if(x == 1) ans = 1;
        rep(j, 1, tot) {
            if(pre[j] * pre[j] > x) break;
            if(x % pre[j] == 0) {
                int c = 0;
                while(x % pre[j] == 0) {
                    x /= pre[j]; c++;
                }

                if(c % 2 == 1) {
                    if(tmp.first == 0) tmp.first = pre[j];
                    else tmp.second = pre[j];
                }
                else {
                    if(tmp.first == 0 && x > 1) tmp.first = 1;
                    else if(tmp.first > 1) tmp.second = 1;
                    else ans = 1;
                }

            }
        }

        if(x > 1) {
            if(tmp.first == 0) tmp.first = 1, tmp.second = x;
            else tmp.second = x;
        }

        if(tmp.second == 0) tmp.second = 1;

        G[tmp.first].pb(make(tmp.second, i));
        G[tmp.second].pb(make(tmp.first, i));

    }

    if(ans != INF) { printf("%d\n", ans); return 0; }

    rep(i, 1, 1000) ans = min(ans, bfs(i));

    if(ans == INF) puts("-1");
    else printf("%d\n", ans);

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Willems/p/12514384.html