杭电多校(四)2019.7.31--暑假集训

【HDU 6014】

SOLVED

【题目大意】给定N个节点,两点之间距离是节点编号的与,在这样的前提下,求最小生成树,输出代价和路径

【思路】通过lowbit求第一个0的位置,然后令此位为1的值就是最优解

【总结】1.与或非都要先考虑拆分后二进制的特性

               2.检验算法正确性时,验证数据要是自己验证能力的最大值

              (就是多验)        

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<climits>
#include<cmath>
#include<map>
#include<set>
#include<deque>
using namespace std;
const int maxn = 2e5 + 10;
int arr[maxn];
int lowbit(int x)
{
    return x & -x;
}
int main()
{
    ios_base::sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--)
    {
        int N;
        cin >> N;
        int cal = 0;
        for (int i = 2; i <= N; i++)
        {
            if ((i & 1) == 0)
                arr[i] = 1;
            else
            {
                int t =lowbit((i + lowbit(i)));
                if (t <= N)
                    arr[i] = t;
                else
                {
                    arr[i] = 1;
                    cal++;
                }
            }
        }
        cout << cal << "\n";
        for (int i = 2; i <= N; i++)
        {
            cout << arr[i];
            if (i != N)
                cout << ' ';
        }
        cout << "\n";
    }
}
View Code

【HDU 6015】

UNSOLVED


【HDU 6016】

UNSOLVED


【HDU 6017】

UNSOLVED


【HDU 6018】

UNSOLVED


【HDU 6019】

UNSOLVED


【HDU 6020】

SOLVED

【题目大意】给一个4*4的数字谜题,能否恢复到指定形状

【思路】数字谜题的结论

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<climits>
#include<cmath>
#include<map>
#include<set>
#include<deque>
#include<unordered_map>
using namespace std;
struct node
{
    int arr[5][5];
    bool operator<(const node& a)const
    {
        for (int i = 1; i <= 4; i++)
        {
            for (int j = 1; j <= 4; j++)
            {
                if (arr[i][j] >= a.arr[i][j])
                    return false;
            }
        }
        return true;
    }
    node() {};
    node(const int a[][5])
    {
        for (int i = 1; i <= 5; i++)
        {
            for (int j = 1; j <= 5; j++)
            {
                arr[i][j] = a[i][j];
            }
        }
    }
};
map<node, int>mp;
int arr[16];
const int mx[4] = { 0,-1,0,1 };
const int my[4] = { 1,0,-1,0 };
int main()
{
    ios_base::sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--)
    {
        int cal = 0;
        int px;
        for (int i = 1; i <= 16; i++)
        {
            int n;
            cin >> n;
            if (n == 0)
            {
                px = (i - 1) / 4 + 1;
                continue;
            }
            arr[++cal] = n;
        }
        int cnt = 0;
        for (int i = 1; i <= 15; i++)
        {
            for (int j = i + 1; j <= 15; j++)
            {
                if (arr[i] > arr[j])
                    cnt++;
            }
        }
        if ((cnt + 4 - px) % 2 == 0)
            cout << "Yes\n";
        else
            cout << "No\n";
    }
}
View Code

【HDU 6021】

UNSOLVED


【HDU 6022】

UNSOLVED


【HDU 6023】

SOLVED

【题目大意】

【思路】对素数进行特殊处理,先求N^1/5,于是剩下的素数的幂次最高只能是4了,可以二分开根迅速求解

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll pri[10001];
int vis[10001];
int cntp;
void init()
{
    for (ll i = 2; i < 10000; i++)
    {
        if (!vis[i])
        {
            cntp++;
            pri[cntp] = i;
        }
        for (int j = 1; j <= cntp&&pri[j]*i<10000; j++)
        {
            vis[i*pri[j]] = 1;
            if (i%pri[j] == 0)
            {
                break;
            }
            
        }
    }
}
ll sqrt(ll num,int d)
{
    ll l = 1, r = num;
    while (l <= r)
    {
        ll mid = (l+r) / 2;
        ll tmp = LLONG_MAX;
        if(d==3)
        {
            tmp = tmp / mid;
        }
        if (d == 4)
        {
            tmp = tmp / mid;
            tmp /= mid;
        }
        if (tmp / mid < mid)
        {
            r = mid - 1;
            continue;
        }
        tmp = 1;
        for (int i = 1; i <= d; i++)
            tmp *= mid;
        if (tmp == num)
            return mid;
        if (tmp > num)
            r = mid - 1;
        else
            l = mid + 1;
    }
    return 0;
}
int main()
{
    init();
    int T;
    scanf("%d", &T);
    while (T--)
    {
        ll n;
        scanf("%lld", &n);

        int ans = INT_MAX;
        for (int i = 1; i <= cntp; i++)
        {
            if (pri[i] > n)
                break;
            int cnt = 0;
            while (n%pri[i] == 0)
            {
                cnt++;
                n/= pri[i];
            }
            //if (cnt)
            //    printf("cnt %d pri %lld\n", cnt, pri[i]);
            if (cnt < ans && cnt)
                ans = cnt;
        }
        int res = INT_MAX;
        if (n>1)
        {
            if (sqrt(n, 4))
                res = min(res, 4);
            else
            {
                if (sqrt(n, 2))
                    res = min(res, 2);
            }
            if (sqrt(n, 3))
                res = min(res, 3);
            if (res == INT_MAX && n > 4500)
                res = 1;
        }
        printf("%d\n", min(ans,res));
    }    //printf("1000000000000000000 %lld  %lld\n", sqrt(1000000000000000000, 3), sqrt(1000000000000000000, 2));
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/rentu/p/11297739.html