• 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest


    Contest Info


    传送门

    Solved A B C D E F G H I J K L
    9 / 12 O O O - O - Ø Ø O - O O
    • O 在比赛中通过
    • Ø 赛后通过
    • ! 尝试了但是失败了
    • - 没有尝试

    Solutions


    A. Auxiliary Project

    简单dp即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/11 13:13:46
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e6 + 5;
     
    const int mp[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
    const int val[] = {-1, -1, 1, 7, 4, 5, 9, 8, -1, -1, -1};
    int n;
    int dp[N];
     
    void run() {
        freopen("auxiliary.in", "r", stdin);
        freopen("auxiliary.out", "w", stdout);
        cin >> n;
        memset(dp, -1, sizeof(dp));
        dp[0] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < 10; j++) if (val[j] != -1 && i >= j && dp[i - j] != -1) {
                dp[i] = max(dp[i], dp[i - j] + val[j]);
            }   
        }
        cout << dp[n] << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    B. Boolean Satisfiability

    开心签到。

    Code
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define TM "boolean"
     
    char buf[1007];
    int chs[57][2];
    int main() {
    #ifndef LOCAL
    	freopen(TM".in", "r", stdin);
    	freopen(TM".out", "w", stdout);
    #endif
    	scanf("%s", buf);
    	int l=strlen(buf);
    	memset(chs,0,sizeof chs);
    	int qf=false;
    	for(int i=0; i<l; i++) {
    		switch(buf[i]) {
    			case '~':
    				qf=true;
    				break;
    			case 'a' ... 'z':
    				chs[buf[i]-'a'][qf]=1;
    				qf=false;
    				break;
    			case 'A' ... 'Z':
    				chs[buf[i]-'A'+26][qf]=1;
    				qf=false;
    				break;
    		}
    	}
    	long long ans=1;
    	bool ok=false;
    	for(int i=0; i<52; i++) {
    		if(chs[i][0]&&chs[i][1])  ok=true;
    	}
    	if(!ok) {
    		for(int i=0; i<52; i++) {
    			if(chs[i][0] || chs[i][1]) 
    				ans*=2;
    		}
    		ans--;
    	} else {
    		for(int i=0; i<52; i++) {
    			if(chs[i][0]||chs[i][1]) {
    				ans*=2;
    			}
    		}
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    C. Consonant Fencity

    因为不同字符数量很少,故直接状压枚举即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/11 14:53:04
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
    const int ban[] = {0, 'e' - 'a', 'i' - 'a', 'o' - 'a', 'u' - 'a', 'w' - 'a', 'y' - 'a'};
     
    string str;
    int cnt[26], mp[26], mp2[26], change[26];
    int a[26][26];
     
    bool ok(int c) {
        for (int i = 0; i < 7; i++) {
            if (c == ban[i]) {
                return false;
            }
        }
        return true;
    }
     
    void run() {
        freopen("consonant.in", "r", stdin);
        freopen("consonant.out", "w", stdout);
        cin >> str;
        int n = str.length();
        for (int i = 0; i < n; i++) {
            if (ok(str[i] - 'a')) {
                ++cnt[str[i] - 'a'];
            }
        }
        int tot = 0;
        for (int i = 0; i < 26; i++) {
            if (cnt[i]) {
                mp[i] = tot;
                mp2[tot] = i;
                ++tot;
            }
        }
        if (tot == 0) {
            cout << str << '
    ';
            return;   
        }
        for (int i = 0; i < n; i++) {
            if (i + 1 < n) {
                if (ok(str[i] - 'a') && ok(str[i + 1] - 'a')) {
                    ++a[mp[str[i] - 'a']][mp[str[i + 1] - 'a']];
                    ++a[mp[str[i + 1] - 'a']][mp[str[i] - 'a']];
                }
            }
        }
        //for (int i = 0; i < tot; i++) {
            //for (int j = 0; j < tot; j++) {
                //cout << a[i][j] << ' ';
            //} cout << '
    ';
            //cout << mp2[i] << '
    ';
        //}
        int ans = 0;
        for (int sta = 0; sta < 1 << (tot - 1); sta++) {
            int res = 0;
            for (int i = 0; i < tot - 1; i++) {
                if (sta >> i & 1) {
                    for (int j = 0; j < tot; j++) {
                        if (!(sta >> j & 1)) {
                            res += a[i][j];
                        }
                    }
                }
            }
            if (res > ans) {
                ans = res;
                memset(change, 0, sizeof(change));
                for (int i = 0; i < tot; i++) {
                    if (sta >> i & 1) {
                        change[mp2[i]] = 1;
                    }
                }   
            }
        }
        for (int i = 0; i < n; i++) {
            if (change[str[i] - 'a']) {
                str[i] = str[i] - 'a' + 'A';
            }
        }
        cout << str << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    E. Equal Numbers

    显然最后每个数只能都变为他们的(lcm)或者变到某一个数上面去。
    那么对这两种情况都处理一下取最小值即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/11 15:57:13
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 3e5 + 5, MAX = 1e6 + 5;
     
    int n;
    int cnt[MAX];
    struct node {
        int c, v;
        bool operator < (const node& A)const {
            return c > A.c;
        }
    };
     
    int ans1[MAX], ans2[MAX], to[MAX];
     
    void solve1(int* ans) {
        int k = n;
        priority_queue <node> q;
        for (int i = 1; i < MAX; i++) if (cnt[i]) {
            q.push(node {cnt[i], i});
        }
        int cur = 0;
        while (!q.empty()) {
            node now = q.top(); q.pop();
            if (k < now.c) break;
            if (to[now.v] == now.v) continue;
            cur += now.c;
            --ans[cur];
            k -= now.c;
        }
    }
     
    void solve2(int* ans) {
        int k = n;
        priority_queue <node> q;
        for (int i = 1; i < MAX; i++) if (cnt[i]) {
            q.push(node {cnt[i], i});
        }
        int cur = 0;
        while (!q.empty()) {
            node now = q.top(); q.pop();
            if (k < now.c) break;
            cur += now.c;
            if (cur != now.c) --ans[cur];
            k -= now.c;
        }   
    }
     
    void run() {
        freopen("equal.in", "r", stdin);
        freopen("equal.out", "w", stdout);
        cin >> n;
        for (int i = 1; i <= n; i++) {
            int x; cin >> x;
            ++cnt[x];
        }
        int tot = 0;
        for (int i = 1; i < MAX; i++) if (cnt[i]) {
            ++tot;
            for (int j = i; j < MAX; j += i) {
                if (cnt[j]) {
                    to[i] = j;
                }
            }
        }
        solve1(ans1), solve2(ans2);
        ans1[0] += tot, ans2[0] += tot;
        for (int i = 1; i <= n; i++) {
            ans1[i] += ans1[i - 1];
            ans2[i] += ans2[i - 1];
        }
        for (int i = 0; i <= n; i++) {
            int ans = min(ans1[i], ans2[i]);   
            cout << ans << " 
    "[i == n];
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
    

    G. Grand Test

    题意:
    给定(n)(m)条边的有向图,现在要找到起点(S)和终点(T),并且满足(S ightarrow T)存在三条除开起点终点之外的点不重复的路径,并且要输出路径。

    思路:
    画图即可发现,若满足题中条件,一定具有“由两个环拼接起来”的特征,即两个环共享一部分,画个图就比较显然了。
    那么找环的问题我们可以在(dfs)树或者(bfs)树上解决。
    对于每条返祖边((u,v)),暴力给树上(u ightarrow v)的路径染色。若某条边有两种颜色那么说明存在两个环重合,直接扣出来暴力(dfs)找路径即可。
    细节见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/12 15:31:13
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n, m;
    vector <pii> G[N], edges;
    vector <int> nG[N];
    pii color[N], f[N];
    int vis[N], dfn, c1, c2;
    bool flag;
     
    int paint(int x, int c) {
        if (color[x].fi == -1) {
            color[x].fi = c;
            return 0;
        }
        color[x].se = c;
        return 1;
    }
     
    void paint(int x, int y, int c) {
        while (x != y) {
            pii now = f[x];
            if (paint(now.se, c)) {
                flag = true;
                c1 = color[now.se].fi;
                c2 = color[now.se].se;
            }   
            x = now.fi;
        }
    }
     
    void dfs(int u, int fa, int t) {
        if (flag) return;
        f[u] = MP(fa, t);
        vis[u] = ++dfn;
        for (auto it : G[u]) {
            int v = it.fi, id = it.se;
            if (v == fa) continue;
            if (!vis[v]) {
                dfs(v, u, id);
            } else if (vis[v] < vis[u]) {
                if (flag) continue;
                paint(u, v, id);
            }
        }
    }
     
    int d[N];
     
    bool ok(int id, int c) {
        return color[id].fi == c || color[id].se == c || id == c;
    }
     
    void find() {
        for (int i = 1; i <= m; i++) {
            if (ok(i, c1) || ok(i, c2)) {
                int u = edges[i].fi, v = edges[i].se;
                nG[u].push_back(v);
                nG[v].push_back(u);
                ++d[u], ++d[v];
            }
        }
    }
     
    vector <vector <int>> cyc(3);
    int S, T, t;
     
    void go(int u, int fa) {
        if (u == T) return;
        for (auto v : nG[u]) if (v != fa) {
            cyc[t].push_back(v);
            go(v, u);
            if (u == S) ++t;
        }
    }
     
    void run() {
        cin >> n >> m;
        flag = false;
        t = dfn = 0;
        for (int i = 0; i < 3; i++) {
            cyc[i].clear();
        }
        for (int i = 1; i <= n; i++) {
            G[i].clear();
            nG[i].clear();
            vis[i] = d[i] = 0;
        }
        for (int i = 1; i <= m; i++) {
            color[i] = MP(-1, -1);
        }
        edges.clear(), edges.push_back(MP(0, 0));
        for (int i = 1; i <= m; i++) {
            int u, v; cin >> u >> v;
            G[u].push_back(MP(v, i));
            G[v].push_back(MP(u, i));
            edges.push_back(MP(u, v));
        }
        for (int i = 1; i <= n; i++) {
            if (!vis[i]) {
                dfs(i, 0, 0);
            }
        }
        
        if (!flag) {
            cout << -1 << '
    ';
            return;
        }
        find();
        S = -1, T = -1;
        for (int i = 1; i <= n; i++) {
            if (d[i] >= 3) {
                if (S == -1) {
                    S = i;
                } else if (T == -1) {
                    T = i;
                }
            }
        }
        go(S, 0);
        cout << S << ' ' << T << '
    ';
        for (int i = 0; i < 3; i++) {
            cout << sz(cyc[i]) + 1 << ' ' << S;
            for (auto it : cyc[i]) {
                cout << ' ' << it;
            }
            cout << '
    ';
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        freopen("grand.in", "r", stdin);
        freopen("grand.out", "w", stdout);
        int T; cin >> T; while(T--)
        run();
        return 0;
    }
    

    H. Hidden Supervisors

    题意:
    给定一个森林,现在每棵树两两相邻结点可以匹配,一个结点最多只能匹配一次。
    现在将所有树拼接为一颗树,要求怎么拼接,最后的匹配对数最大。

    思路:

    • 对于一颗树,显然自底向上进行两两匹配最优。最后一颗树只会剩下0/1个根节点以及若干个叶子结点,接下来考虑不同树的"叶子-根"的匹配。
    • 考虑拼接,直接将剩下(1)个根节点的树拼接到前面结点中即可,并且更新树的叶子结点;如果前面没有结点,则直接与树根相连,但此时不会产生新的匹配。
    • 拼接时要按照叶子结点从大到小的顺序进行拼接,这样更新过后的结点数会更多,更有利于后续树根的匹配。

    细节见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/11 17:03:22
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n;
    int fa[N];
    bool vis[N];
    int ans, tot;
    vector <int> G[N], t;
    vector <pair<vector<int>, int>> a;
     
    void dfs(int u) {
        t.push_back(u);
        for (auto v : G[u]) {
            dfs(v);
            if (!vis[u] && !vis[v]) {
                vis[u] = vis[v] = true;
                ++ans;
            }
        }
    }
     
    void gao(int u) {
        t.clear();
        dfs(u);
        vector <int> tmp = t;
        t.clear();
        for (auto it : tmp) {
            if (!vis[it]) {
                t.push_back(it);
            }
        }
        int f = 0;
        for (int i = 0; i < sz(t); i++) {
            if (fa[t[i]] == 0 && t[i] != 1) {
                swap(t[sz(t) - 1], t[i]);
                f = 1;
                break;
            }
        }
        a.push_back(MP(t, f));
    }
     
    void run() {
        freopen("hidden.in", "r", stdin);
        freopen("hidden.out", "w", stdout);
        cin >> n;
        for (int i = 2; i <= n; i++) {
            cin >> fa[i];
            if (fa[i] > 0) {
                G[fa[i]].push_back(i);
            }
        }
        for (int i = 1; i <= n; i++) {
            if (fa[i] == 0) {
                gao(i);
            }
        }
        vector <vector <int>> v1;
        vector <int> v0;
        for (auto& it : a) if (sz(it.fi)) {
            if (it.se) v1.push_back(it.fi);
            else {
                for (auto& it2 : it.fi) {
                    v0.push_back(it2);
                }
            }
        }
        sort(all(v1), [&] (vector <int> A, vector <int> B) {
            return sz(A) > sz(B);
        });
        for (auto& v : v1) {
            if (sz(v0)) {
                ++ans;
                fa[v[sz(v) - 1]] = v0.back();
                v0.pop_back();
                v.pop_back();
            }
            if (sz(v)) {
                for (auto it : v) {
                    v0.push_back(it);
                }
            }
        }
        cout << ans << '
    ';
        for (int i = 2; i <= n; i++) {
            if (fa[i] == 0) fa[i] = 1;
            cout << fa[i] << " 
    "[i == n];
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    I. Intelligence in Perpendicularia

    答案即为总边长减去里面的边长。

    Code
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define TM "intel"
    int xs[1007], ys[1007];
     
    int main() {
    #ifndef LOCAL
    	freopen(TM".in", "r", stdin);
    	freopen(TM".out", "w", stdout);
    #endif
    	int n; scanf("%d", &n);
    	for(int i=0; i<n; i++) {
    		scanf("%d%d", &xs[i], &ys[i]);
    		xs[i]+=1000001;
    		ys[i]+=1000001;
    	}
    	int mx,my,Mx,My;
    	mx=Mx=xs[0], my=My=ys[0];
    	for(int i=0; i<n; i++) mx=min(mx,xs[i]), my=min(my,ys[i]), Mx=max(Mx,xs[i]), My=max(My,ys[i]);
    	xs[n]=xs[0], ys[n]=ys[0];
     
    	long long ans1=0, ans2=0;
    	for(int i=1; i<=n; i++) {
    		int x1=xs[i], x2=xs[i-1];
    		int y1=ys[i], y2=ys[i-1];
    		if(x1==x2) {
    			if(y1>y2) swap(y1,y2);
    			int v=y2-y1;
    			ans2+=v;
    		} else {
    			if(x1>x2) swap(x1,x2);
    			int v=x2-x1;
    			ans1+=v;
    		}
    	}
    	ans1 -= (Mx-mx)*2;
    	ans2 -= (My-my)*2;
    	printf("%lld
    ", ans1+ans2);
    	return 0;
    }
    
    

    K. Kotlin Island

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/11 13:24:07
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 100 + 5;
     
    int r, c, n;
    int rows[N], cols[N];
     
    void run() {
        freopen("kotlin.in", "r", stdin);
        freopen("kotlin.out", "w", stdout);
        cin >> r >> c >> n;
        int x, y;
        for (int i = 1; 1ll * i * i <= n; i++) {
            if (n % i == 0) {
                x = i - 1, y = n / i - 1;
                if (2 * x + 1 <= r && 2 * y + 1 <= c) {
                    break;
                }
                x = n / i - 1, y = i - 1;
                if (2 * x + 1 <= r && 2 * y + 1 <= c) {
                    break;
                }           
            }
        }
        if (2 * x + 1 <= r && 2 * y + 1 <= c) {
            for (int i = 2; i <= 2 * x; i += 2) {
                rows[i] = 1;
            }
            for (int i = 2; i <= 2 * y; i += 2) {
                cols[i] = 1;
            }
            for (int i = 1; i <= r; i++) {
                for (int j = 1; j <= c; j++) {
                    if (rows[i] || cols[j]) {
                        cout << "#";
                    } else cout << ".";
                }
                cout << '
    ';
            }
        } else {
            cout << "Impossible" << '
    ';
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    L. Little Difference

    题意:
    给定一个数(n,nleq 10^{18}),将其分为若干个相差至多为(1)的数的乘积,如果有无限个则输出(-1)

    思路:
    显然最后的分解式中有(1)则有无限多个分解方案,此时只可能出现在(n=1,n=2)的情况中。
    分解式中有(1,2)个数的情况我们可以直接考虑,接下来就处理分解式中有大于(2)个数的情况,此时每个数最多为(10^6)。那么我们可以直接枚举分解式中较小的那个数即可。
    详见代码:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/6/11 14:13:21
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <functional>
    #include <numeric>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << std::endl; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        freopen("little.in", "r", stdin);
        freopen("little.out", "w", stdout);
        ll n; cin >> n;
        ll p = n;
        while (p % 2 == 0) {
            p /= 2;
        }
        if (p == 1) {
            cout << -1 << '
    ';
            return;
        }
        
        vector <vector <ll>> ans;
        ans.push_back({n});
        ll t = sqrt(n + 0.5);
        while (t * t > n) --t;
        if (t * t == n) {
            ans.push_back({t, t});
        }
        if (t * (t + 1) == n) {
            ans.push_back({t, t + 1});   
        }
        for (int i = 2; i <= min(n, 1000000ll); i++) {
            if (n % i) continue;
            vector <ll> res;
            res.push_back(i);
            ll x = n / i;
            while (x % i == 0) {
                x /= i;
                res.push_back(i);
            }
            if (x == 1) {
                ans.push_back(res);
                continue;
            }
            ll x2 = x;
            if (x % (i + 1) == 0) {
                while (x % (i + 1) == 0) {
                    x /= (i + 1);
                }
                if (x == 1) {
                    x = x2;
                    while (x % (i + 1) == 0) {
                        x /= (i + 1);
                        res.push_back(i + 1);
                    }
                    sort(all(res));
                    ans.push_back(res);
                }
            }
        }
        vector <vector<ll>> result;
        sort(all(ans));
        result.push_back(ans[0]);
        for (int i = 1; i < sz(ans); i++) {
            if (ans[i] != ans[i - 1]) {
                result.push_back(ans[i]);
            }
        }
        cout << sz(result) << '
    ';
        for (auto seq : result) {
            cout << sz(seq);
            for (auto it : seq) {
                cout << ' ' << it;
            }
            cout << '
    ';   
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    【java】定时任务@Scheduled
    20180513 实参 形参 数组
    20180513 实参 形参
    20180513 数组 实参 形参
    <转载>二维数组回形遍历
    20180318 代码错题(8)
    20180318 代码错题(7)
    20180318 代码错题(6)
    20180318 代码错题(5)
    20180318 bit置0
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/13145159.html
Copyright © 2020-2023  润新知