zoukankan      html  css  js  c++  java
  • 2019年杭电多校第四场

    1001 AND Minimum Spanning Tree(HDU6614)

    题意

    要你构造一棵最小生成树,边权是两顶点的编号的与值。

    思路

    对于(2^i-1)(2^i)是否小于等于(n),如果是则与(2^i)连边,其他的数则看其二进制下最后一个(0)在哪,假设是在(x),那么就与(2^x)连边。

    代码实现如下:

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 1000000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t, n;
    vector<int> vec;
    
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            int ans = 0;
            vec.clear();
            for(int i = 2; i <= n; ++i) {
                int num = 0;
                for(int j = 0; j <= 20; ++j) {
                    if(i <= (1<<j)) {
                        num = (1<<j);
                        break;
                    }
                }
                if(i == num - 1) {
                    if(num <= n) vec.push_back(num);
                    else vec.push_back(1), ++ans;
                } else {
                    for(int j = 0; j <= 20; ++j) {
                        if(!(i & (1<<j))) {
                            vec.push_back((1<<j));
                            break;
                        }
                    }
                }
            }
            printf("%d
    ", ans);
            int flag = 0;
            for(int i = 0; i < vec.size(); ++i) {
                if(flag) printf(" ");
                flag = 1;
                printf("%d", vec[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    

    1003 Divide the Stones(HDU6616)

    题意

    要你把个石子分成(k)堆,每堆有(frac{n}{k})个石子,使得这(k)堆石子重量相同,每个石子的重量为(i)

    思路

    对于(frac{n}{k})偶数我们发现蛇形填数是可以使得其相等的,那么对于奇数我们只需要拿出前(3k)个来填,剩余的按照偶数的进行处理即可。

    奇数的时候我们首先确定第一列分别为(1)~(k),第二列肯定要错位填数,通过计算可以得到第(frac{k}{2}+1)(2k),然后(frac{k}{2}+2)(1),以此类推。第三列则用(frac{3(3*k+1)}{3})来减即可。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 1000000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t, n, k;
    
    int main() {
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &k);
            if(1LL * n * (n + 1) / 2 % k || (n == k && n != 1)) {
                printf("no
    ");
                continue;
            }
            printf("yes
    ");
            int x = k, y = n / k;
            int mp[x+5][y+5];
            if(y & 1) {
                for(int i = 1; i <= x; ++i) mp[i][1] = i;
                mp[k/2+1][2] = 2 * k;
                for(int i = k / 2 + 2; i <= x; ++i) mp[i][2] = i - k / 2 - 1 + k;
                for(int i = 1; i <= k / 2; ++i) mp[i][2] = k + k / 2 + i;
                for(int i = 1; i <= x; ++i) mp[i][3] = 4 * k + k / 2 + 2 - mp[i][1] - mp[i][2];
                int nx = 1, ny = 4;
                for(int i = 3 * k + 1; i <= n; ++i) {
                    mp[nx][ny] = i;
                    if(ny % 2 == 0) {
                        if(nx == x) {
                            ++ny;
                        } else {
                            ++nx;
                        }
                    } else {
                        if(nx == 1) {
                            ++ny;
                        } else {
                            --nx;
                        }
                    }
                }
            } else {
                int nx = 1, ny = 1;
                for(int i = 1; i <= n; ++i) {
                    mp[nx][ny] = i;
                    if(ny % 2 == 1) {
                        if(nx == x) {
                            ++ny;
                        } else {
                            ++nx;
                        }
                    } else {
                        if(nx == 1) {
                            ++ny;
                        } else {
                            --nx;
                        }
                    }
                }
            }
            for(int i = 1; i <= x; ++i) {
                for(int j = 1; j <= y; ++j) {
                    printf("%d%c", mp[i][j], j == y ? '
    ' : ' ');
                }
            }
        }
        return 0;
    }
    

    1007 Just an Old Puzzle(HDU6620+华容道+逆序对)

    思路

    (0)变成(16)然后矩阵合并成一列求出逆序对,加上(0)的初始位置如果是偶数则可以构造,否则就不能构造。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 1000000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t;
    int a[20];
    
    int main() {
        scanf("%d", &t);
        while(t--) {
            int ans = 0;
            for(int i = 0; i < 16; ++i) {
                scanf("%d", &a[i]);
                if(a[i] == 0) ans += i / 4 + 1 + i % 4 + 1;
                if(a[i] == 0) a[i] = 16;
                for(int j = 0; j <= i; ++j) {
                    if(a[j] > a[i]) ++ans;
                }
            }
            if(ans & 1) printf("No
    ");
            else printf("Yes
    ");
        }
        return 0;
    }
    

    1008 K-th Closest Distance(6621+主席树+二分)

    题意

    对于一个数组(a)查询(q)次,每次问区间([L,R])中距离(p)是第(k)大的是多少(第(i)个数与(p)的距离为(|a_i-p|))。

    思路

    二分答案然后看([p-ans,p+ans])内有没有(k)个数。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 1000000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t, n, q, l, r, p, k, cnt;
    int a[maxn], root[maxn];
    
    struct node {
        int l, r, sum;
    }tree[maxn*40];
    
    void update(int l, int r, int &x, int &y, int pos) {
        tree[++cnt] = tree[y], tree[cnt].sum++, x = cnt;
        if(l == r) return;
        int mid = (l + r) >> 1;
        if(mid >= pos) update(l, mid, tree[x].l, tree[y].l, pos);
        else update(mid + 1, r, tree[x].r, tree[y].r, pos);
    }
    
    int query(int l, int r, int x, int y, int L, int R) {
        if(l >= L && r <= R) return tree[y].sum - tree[x].sum;
        if(l == r) return 0;
        int mid = (l + r) >> 1;
        if(R <= mid) return query(l, mid, tree[x].l, tree[y].l, L, R);
        else if(L > mid) return query(mid + 1, r, tree[x].r, tree[y].r, L, R);
        else return query(l, mid, tree[x].l, tree[y].l, L, mid) + query(mid + 1, r, tree[x].r, tree[y].r, mid + 1, R);
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
    FIN;
    time_t s = clock();
    #endif // ONLINE_JUDGE
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &q);
            int mx = 0;
            cnt = 0;
            for(int i = 1; i <= n; ++i) {
                scanf("%d", &a[i]);
                mx = max(mx, a[i]);
            }
            for(int i = 1; i <= n; ++i) {
                update(1, mx, root[i], root[i-1], a[i]);
            }
            int las = 0;
            while(q--) {
                scanf("%d%d%d%d", &l, &r, &p, &k);
                l = l ^ las, r = r ^ las, p = p ^ las, k = k ^ las;
                int ub = mx, lb = 0, mid, ans = mx;
                while(ub >= lb) {
                    mid = (ub + lb) >> 1;
                    if(query(1, mx, root[l-1], root[r], p - mid, p + mid) >= k) {
                        ans = mid;
                        ub = mid - 1;
                    } else {
                        lb = mid + 1;
                    }
                }
                las = ans;
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
    

    1010 Minimal Power of Prime(HDU6623+素数筛)

    题意

    给你(n),问你(n)的素因子中最小的次数是多少。

    思路

    我们首先把(4000)内的素数筛出来,如果(n)还有剩余那么可以发现除了(p^4,p^3,p^2,(p_1p_2)^2)外其他情况指数最小都是(1),对于这几种情况分别开方就行,最后与小于(4000)的素数的最小次数取(min)就行。

    本题与HDU5447(题解)很像,想清楚就会发现其实很简单,根本就不用把(n)完全唯一分解出来。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 1000000007;
    const int maxn = 4000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t, tot;
    LL n;
    bool v[maxn];
    int p[maxn];
    
    void init() {
        for(int i = 2; i < maxn; ++i) {
            if(!v[i]) {
                p[tot++] = i;
            }
            for(int j = 0; j < tot && i * p[j] < maxn; ++j) {
                v[i*p[j]] = 1;
                if(i % p[j] == 0) break;
            }
        }
    }
    
    int main() {
        init();
        scanf("%d", &t);
        while(t--) {
            scanf("%lld", &n);
            int cnt = inf;
            int flag = 0;
            for(int i = 0; i < tot; ++i) {
                if(n % p[i] == 0) {
                    int num = 0;
                    while(n % p[i] == 0) {
                        ++num;
                        n /= p[i];
                    }
                    if(num == 1) {
                        flag = 1;
                    }
                    cnt = min(cnt, num);
                }
            }
            if(flag) {
                printf("1
    ");
                continue;
            }
            if(n == 1) {
                printf("%d
    ", cnt);
                continue;
            }
            LL tmp = pow(n, 0.25);
            if(tmp * tmp * tmp * tmp == n) {
                cnt = min(cnt, 4);
            } else {
                ++tmp;
                if(tmp * tmp * tmp * tmp == n) {
                    cnt = min(cnt, 4);
                } else {
                    tmp = pow(n, 0.5);
                    if(tmp * tmp == n) {
                        cnt = min(cnt, 2);
                    } else {
                        ++tmp;
                        if(tmp * tmp == n) {
                            cnt = min(cnt, 2);
                        } else {
                            tmp = pow(n, 1.0 / 3);
                            if(tmp * tmp * tmp == n) {
                                cnt = min(cnt, 3);
                            } else {
                                ++tmp;
                                if(tmp * tmp * tmp == n) {
                                    cnt = min(cnt, 3);
                                } else {
                                    cnt = min(cnt, 1);
                                }
                            }
                        }
                    }
                }
            }
            printf("%d
    ", cnt);
        }
        return 0;
    }
    
  • 相关阅读:
    对jquery的 attr()和prop()理解
    你真的了解javascript吗
    js代码的一些小技巧
    导出导入数据库
    Mysql授权root用户远程登录
    Centos 忘记root密码怎么办?
    linux挂载概念简述:
    centos7防火墙设置
    centos 防火墙
    centos共享目录
  • 原文地址:https://www.cnblogs.com/Dillonh/p/11280835.html
Copyright © 2011-2022 走看看