• HZNU 2019 Summer training 6 -CodeForces


    A - Infinite Sequence  CodeForces - 622A 

    题目大意:给你一个这样的数列1,1,2,1,2,3,1,2,3,4,1,2,3,4,5.。。。就是从1~n排列(n++).最后问你第n个位置是什么数字。

    思路:如果你花点时间列数列的话会发现,1~n的最后一位对应的位置是1~n的和,那我们就大胆使用二分进行搜索这位数。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<string>
    #include<vector>
    #include<ctime>
    #include<stack>
    #include<fstream>
    #include<iomanip>
    #include<deque>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define mm(a,b) memset(a,b,sizeof(a))
    #define maxn 300
    #define len 150000000+5
    #define inf 0x3f3f3f3f
    int gcd(int a, int b)
    {
        return a % b == 0 ? b : gcd(b, a%b);
    }
    int main()
    {
        ll n;
        scanf("%lld", &n);
        ll l = 1, r = 1e8, mid;
        while (l <= r)
        {
            mid = (l + r) / 2;
            if ((mid + 1)*mid / 2 >= n && (mid - 1)*mid / 2 < n)
                break;
            else if ((mid + 1)*mid / 2 < n)
                l = mid + 1;
            else r = mid - 1;
        }
        ll maxx = (mid + 1)*mid / 2;
        ll ans = mid - (maxx - n);
        printf("%lld
    ", ans);
        return 0;
    }
    View Code

    B - Optimal Number Permutation CodeForces - 622D 

    题意:给你一个数组,长度为2*n,出现的数字是1~n(每个数字出现两遍)。两个相同数字之间定义了距离di=xi-yi(xi>yi),最后问如何构造这个数组的序列,使得求和.值最小。

    思路:看到这样的题先不要着急,想列一下式子,我们就可以发现,你可以构造出一个s=0的数列。

    例如:

    n=1 1

    n=2 1 1 2 2

    n=3 1 3 1 2 2 3

    n=4 1 2 4 2 1 3 3 4

    数字从1~n-1开始排序,n因为怎么样都是0,可以插空排。然后如果这个数字是奇数,我们从左边开始放,偶数从右边开始放。排放就按使得该数(di+i-n)=0的位置排(我也不知道为什么不会覆盖)。然后最后放n。

    有个坑点(我自己的),总是数组开小,给你n<=500000,你要开两倍啊。TAT

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<string>
    #include<vector>
    #include<ctime>
    #include<stack>
    #include<fstream>
    #include<iomanip>
    #include<deque>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    #define mm(a,b) memset(a,b,sizeof(a))
    #define maxn 2*500000+50
    #define len 150000000+5
    #define inf 0x3f3f3f3f
    int gcd(int a, int b)
    {
        return a % b == 0 ? b : gcd(b, a%b);
    }
    int ans[maxn];
    int main()
    {
        int n;
        memset(ans, 0, sizeof(ans));
        scanf("%d", &n);
        int left = 1, right = n + 1;
        for (int i = 1; i <= n - 1; i++)
        {
            if (i % 2 == 1)
            {
                ans[left] = i;
                ans[left + n - i] = i;
                left++;
            }
            else
            {
                ans[right] = i;
                ans[right + n - i] = i;
                right++;
            }
        }
        for (int i = 1; i <= 2 * n; i++)
        {
            if (!ans[i]) ans[i] = n;
        }
        for (int i = 1; i <= 2 * n; i++)
        {
            printf("%d ", ans[i]);
        }
        printf("
    ");
        return 0;
    }
    View Code

    C - Not Equal on a Segment  CodeForces - 622C 

    题意:给你n个数字和m个询问。询问格式:l,r,x,输出在l~r之间a[i]<>x的下标i。

    思路:在读入数组的时候就需要将和这个数不相等的位置找到啦,往后面找。因为要么区间的第一个数字和x相等,要么不相等。不相等直接输出当前的位置i,相等就需要往后找啦。

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<functional>
    using namespace std;
    const int maxn = 2e5 + 50;
    int a[maxn], f[maxn];
    int main()
    {
        int n, m;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        for (int i = 1; i <= n; i++)
        {
            if (a[i] != a[i + 1])
                f[i] = i + 1;
            else
            {
                int pos = i;
                for (; a[i] == a[i + 1];) i++;
    
                for (int j = pos; j <= i; j++)
                    f[j] = i + 1;
            }
        }
    
        while (m--)
        {
            int l, r, x;
            scanf("%d %d %d", &l, &r, &x);
            int flag = 0;
            for (int i = l; i <= r; i++)
            {
                if (a[i] == x)
                {
                    if (f[i] > r || f[i] == 0) break;
                    printf("%d
    ", f[i]);
                    flag = 1;
                    break;
                }
                else 
                { 
                    printf("%d
    ", i); 
                    flag = 1;
                    break; 
                }
            }
            if (!flag) printf("-1
    ");
        }
        return 0;
    }
    View Code

    D - Ants in Leaves  CodeForces - 622E 

    题意:给你一棵树,一只小蚂蚁在一个叶节点上,他们想回到根节点1,他们可以往自己的父节点爬行,爬行一段花费1个时间点。有个要求是,除了root可以容纳一个ant以外,其它节点只能容纳一只ant,所以如果一个ant在父节点。他的兄弟节点就需要等待一定的时间。问:所有蚂蚁回到叶节点的最小时间是多少?

    思路:实验室的巨巨说,可以逆着想,可以假设所有蚂蚁都在根节点上,那么就是所有蚂蚁到叶节点的最短时间。这题就是需要建树,然后dfs一下,给每个子节点深度赋值。

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<functional>
    using namespace std;
    const int maxn = 5e5 + 50;
    
    int head[maxn * 2], num, cnt, dp[maxn], d[maxn];
    struct node
    {
        int to, next, w;
    }e[maxn*2];
    
    void init()
    {
        num = 0;
        memset(head, -1, sizeof(head));
    }
    
    void add(int u, int v)
    {
        e[num].to = v;
        e[num].next = head[u];
        head[u] = num++;
    }
    
    void dfs(int u, int fa, int depth)
    {
        int flag = 0;
        for (int i = head[u]; ~i; i = e[i].next)
        {
            int v = e[i].to;
            if (v == fa)
                continue;
            flag = 1;
            dfs(v, u, depth + 1);
        }
        if (!flag)
            d[cnt++] = depth;
    }
    
    int main()
    {
        init();
        int n, u, v, ans = 0;
        scanf("%d", &n);
        for (int i = 0; i < n - 1; i++)
        {
            scanf("%d %d", &u, &v);
            add(u, v);
            add(v, u);
        }
        for (int i = head[1]; ~i; i = e[i].next)
        {
            int v = e[i].to;
            cnt = 0;
            dfs(v, 1, 1);
            sort(d, d + cnt);
            for (int j = 1; j < cnt; j++)
                d[j] = max(d[j - 1] + 1, d[j]);
    
            ans = max(ans, d[cnt - 1]);
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    E - The Sum of the k-th Powers CodeForces - 622F 

    题意:   % 109 + 7

    思路:还不会。

  • 相关阅读:
    oracle课堂笔记---第十九天
    oracle课堂笔记--第十八天
    oracle课堂随笔--第十七天
    oracle课堂随笔--第十六天
    oracle课堂随笔--第十五天
    oracle课堂随笔--第十四天
    oracle课堂笔记--第十三天
    oracle课堂随笔--第十一天
    Beta冲刺预备
    个人作业——软件产品分析
  • 原文地址:https://www.cnblogs.com/Tangent-1231/p/11130306.html
Copyright © 2020-2023  润新知