• 江西理工2019 摸底测试题解


    摸底测试链接http://oj.jxust.edu.cn/contest?id=1702

    A.Water

    思路:题面说的是随机操作,但是实际上只是输入数据随机,操作的时候怎么操作都是可以的,只需要用数组存一下每个水瓶倒多少水,然后从第一个开始往后倒,如果有多就传给下一个瓶子,如果不够就直接全部赋给这一个瓶子就行了。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    LL a[100005], b[100005], ans[100005];
    int main()
    {
        LL t, n, m, x, y;
        scanf("%lld", &t);
        while(t--)
        {
            scanf("%lld%lld", &n, &m);
            for(int i = 1;i <= n;i++)
            {
                scanf("%lld", &a[i]);
                b[i] = 0;
            }
            for(int i = 1;i <= m;i++)
            {
                scanf("%lld%lld", &x, &y);
                b[x] += y;
            }
            for(int i = 1;i <= n;i++)
            {
                if(b[i] >= a[i])
                {
                    ans[i] = a[i];
                    b[i] -= a[i];
                    //printf("ai = %d
    ", a[i]);
                    //printf("ansi = %d
    ", ans[i]);
                    b[i+1] += b[i];
                }
                else
                {
                    ans[i] = b[i];
                    b[i] = 0;
                }
            }
            for(int i = 1;i <= n;i++)
            {
                if(i < n)
                    printf("%lld ", ans[i]);
                else
                    printf("%lld
    ", ans[i]);
            }
        }
        return 0;
    }
    View Code

     B.Prime Split

    思路:数据范围是4e4,素数只有4000多个,直接n^2复杂度枚举两个素数然后判断一下第三个数是不是素数就行了,但是要注意重复的情况,枚举的时候保证第二个素数不小于第一个素数,然后当第二个素数 >= 第一个素数 && 第三个素数大于第一个素数的时,ans--。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    int s[5005], vis[40005];
    bool sushu(int x)
    {
        for(int i = 2;i*i <= x;i++)
        {
            if(x%i == 0)
                return false;
        }
        return true;
    }
    int main()
    {
        int t, n, temp;
        scanf("%d", &t);
        int cnt = 0;
        for(int i = 2;i < 40000;i++)
        {
            if(sushu(i))
            {
                s[cnt++] = i;
                vis[i] = 1;
            }
        }
        while(t--)
        {
            int ans = 0;
            scanf("%d", &n);
            for(int i = 0;i < cnt;i++)
            {
                for(int j = i;j < cnt;j++)
                {
                    if(n-s[i]-s[j] <= 1)
                        break;
                    //printf("%d %d %d
    ", n,s[i], s[j]);
                    temp = n-s[i]-s[j];
                    if(vis[temp])
                    {
                        ans++;
                        //printf("%d %d %d %d 
    ", n,s[i], s[j], temp);
                        if(s[j] >= s[i] && temp > s[i])
                        {
                            ans--;
                            //printf("%d %d %d %d 
    ", n,s[i], s[j], temp);
                        }
                    }
                }
                if(n - s[i] <= 2)
                    break;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

    C.Connect

    思路:有点绕的最小生成树,用结构体存一下x,y,z,和这是第几个点,再给x,y,z分别排一次序,相邻的点相减得到的边作为kruskal的边,然后就是n个点,3n-3条边的kruskal了。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    int c[200005];
    struct bian
    {
        int val, st, en;
    }b[600006];
    struct node
    {
        int x, y, z, num;
    }a[600005];
    bool cmp(node a, node b)
    {
        return a.x<b.x;
    }
    bool cmpp(node a, node b)
    {
        return a.y<b.y;
    }
    bool cmppp(node a, node b)
    {
        return a.z<b.z;
    }
    bool cmpppp(bian a, bian b)
    {
        return a.val<b.val;
    }
    int Find(int x)
    {
        if(x == c[x])
            return x;
        return c[x] = Find(c[x]);
    }
    void Union(int x, int y)
    {
        x = Find(x);
        y = Find(y);
        if(x == y)
            return;
        c[x] = y;
    }
    int kruskal(int n, int m)
    {
        int sum = 0, res = 0;
        for(int i = 0;i < m && sum != n-1;i++)
        {
            if(Find(b[i].st) != Find(b[i].en))
            {
                Union(b[i].st, b[i].en);
                res += b[i].val;
                sum++;
            }
        }
        return res;
    }
    int main()
    {
        int n, x, xx, y, yy, z, zz, temp;
        scanf("%d", &n);
        for(int i = 0;i < n;i++)
        {
            scanf("%d%d%d", &xx, &yy, &zz);
            c[i+1] = i+1;
            a[i].x=xx, a[i].y=yy, a[i].z=zz, a[i].num=i+1;
        }
        int cnt = 0;
        sort(a, a+n, cmp);
        for(int i = 0;i < n-1;i++)
        {
            temp = a[i+1].x - a[i].x;
            b[cnt].val = temp, b[cnt].st = a[i].num, b[cnt].en = a[i+1].num;
            cnt++;
        }
        sort(a, a+n, cmpp);
        for(int i = 0;i < n-1;i++)
        {
            temp = a[i+1].y - a[i].y;
            b[cnt].val = temp, b[cnt].st = a[i].num, b[cnt].en = a[i+1].num;
            cnt++;
        }
        sort(a, a+n, cmppp);
        for(int i = 0;i < n-1;i++)
        {
            temp = a[i+1].z - a[i].z;
            b[cnt].val = temp, b[cnt].st = a[i].num, b[cnt].en = a[i+1].num;
            cnt++;
        }
        sort(b, b+cnt, cmpppp);
        int ans = kruskal(n, n*3-3);
        printf("%d
    ", ans);
        return 0;
    }
    View Code

    E.Number

    思路:求n模x的逆元,将n分解为若干个正整数之和,使得这些正整数的乘积x最大,n%3 == 0时分成若干个3,余1时把一个3变成4,余2时多一个2。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    LL x, y, n, temp;
    void exoj(LL a, LL b)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return;
        }
        exoj(b, a%b);
        LL t = x;
        x = y;
        y = t-(a/b)*y;
        return;
    }
    int main()
    {
        temp = 1;
        scanf("%lld", &n);
        if(n%3 == 0)
        {
            for(int i = 1;i <= n/3;i++)
                temp *= 3;
        }
        else if(n%3 == 1)
        {
            for(int i = 1;i < n/3;i++)
                temp *= 3;
            temp *= 4;
        }
        else
        {
            for(int i = 1;i < n/3;i++)
                temp *= 3;
            temp *= 6;
        }
        exoj(n, temp);
        printf("%lld
    ", (x+temp)%temp);
        return 0;
    }
    View Code

    F.操作数

    思路:线段树延迟标记,然后查询单点。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    const int maxn = 111111;
    int lazy[maxn*4];
    int SegTree[maxn*4];
    void Pushdown(int root, int l, int r)
    {
        lazy[root*2] += lazy[root];
        lazy[root*2+1] += lazy[root];
        SegTree[root*2] += lazy[root];
        SegTree[root*2+1] += lazy[root];
        lazy[root] = 0;
    }
    void query(int root, int nstart, int nend, int index)
    {
        if(nstart > index || nend < index)
            return;
        if(nstart == nend)
        {
            if(SegTree[root]%2 == 0)
            {
                printf("0
    ");
                return;
            }
            else
            {
                printf("1
    ");
                return;
            }
        }
        if(lazy[root])
            Pushdown(root, nstart, nend);
        int mid = (nstart + nend)/2;
        if(mid >= index)
        query(root*2, nstart, mid, index);
        if(mid < index)
        query(root*2+1, mid+1, nend, index);
    }
    void update(int root, int nstart, int nend, int l, int r)
    {
        if(l > nend || r < nstart) return;
        if(l <= nstart && r >= nend)
        {
            lazy[root]++;
            SegTree[root]++;
            return;
        }
        if(lazy[root])
            Pushdown(root, nstart, nend);
        int mid = (nstart + nend)/2;
        if(mid >= l)
        update(root*2, nstart, mid, l, r);
        if(mid < r)
        update(root*2+1, mid+1, nend, l, r);
    }
    int main()
    {
        int n, m, t, L, R, i;
        scanf("%d%d", &n, &m);
        while(m--)
        {
            scanf("%d",&t);
            if(t == 1)
            {
                scanf("%d%d", &L, &R);
                if(L > R)
                    swap(L, R);
                update(1, 1, n, L, R);
            }
            else
            {
                scanf("%d", &i);
                query(1, 1, n, i);
            }
        }
        return 0;
    }
    View Code

    G.聚会

    思路:组合数二项式定理,推出公式后一个快速幂就解决。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    LL a[100005], b[100005];
    LL inv(LL a, LL b)
    {
        if(a==0) return 1;
        LL res = 1;
        b = b-2;
        while(b)
        {
            if(b&1)
                res = res%MOD*a%MOD;
            a = a%MOD*a%MOD;
            b >>= 1;
        }
        return res;
    }
    int main()
    {
        LL n, ans, temp = 1, tt = 2;
        for(int i = 2;i <= 1e5;i++)
        {
            temp = temp*i%MOD;
            a[i] = temp;
            tt = tt*2%MOD;
            b[i] = tt;
        }
        while(scanf("%lld", &n)!=EOF){
        ans = 0;
        if(n == 1)
        {
            printf("0
    ");
            return 0;
        }
        for(int i = 2;i <= n;i++)
        {
            ans += a[n]*inv(a[i], MOD)%MOD*inv(a[n-i], MOD)%MOD*(b[i]-2)%MOD;
            ans = ans%MOD;
        }
        printf("%lld
    ", ans);
        }
        return 0;
    }
    View Code

    H.地图

    思路:走三遍bfs,前两遍走输入数据,第三遍把前两个地图的障碍物加在一起,如果前两次的步数一样第三次把障碍物加在一起之后也能走通且步数和前两次一样就是YES。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    int vis[505][505];
    int dir[4][2]={1,0, 0,1, -1,0, 0,-1};
    int n, m;
    char s[505][505], ss[505][505];
    struct node
    {
        int x, y, val;
    };
    queue<node> q;
    node road[505][505];
    int bfs(node t, char s[][505])
    {
        while(!q.empty())
            q.pop();
        memset(vis, 0, sizeof(vis));
        vis[0][0] = 1;
        q.push(t);
        node Next, temp;
        while(!q.empty())
        {
            temp = q.front();
            q.pop();
            if(temp.x == n-1 && temp.y == m-1)
                return temp.val;
            for(int i = 0;i < 4;i++)
            {
                Next.x = temp.x + dir[i][0];
                Next.y = temp.y + dir[i][1];
                if(vis[Next.x][Next.y] == 0 && Next.x >= 0&& Next.x < n && Next.y >= 0 && Next.y < m && s[Next.x][Next.y] == '.')
                {
                    Next.val = temp.val + 1;
                    q.push(Next);
                    vis[Next.x][Next.y] = 1;
                }
            }
        }
        return -1;
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        node t;
        t.x = 0, t.y = 0, t.val = 0;
        for(int i = 0;i < n;i++)
            scanf("%s", s[i]);
        int flag1 = bfs(t, s);
        for(int i = 0;i < n;i++)
        {
            scanf("%s", ss[i]);
            for(int j = 0;j < m;j++)
            {
                if(ss[i][j] == '#')
                    s[i][j] = '#';
            }
        }
        int flag2 = bfs(t, ss);
        int flag3 = bfs(t, s);
        if(flag1 == flag2 && flag1 == flag3 && flag1 >= 0)
            printf("YES
    ");
        else
            printf("NO
    ");
        return 0;
    }
    View Code

    I.我是签到题

    思路:两边走,哪边小就把另一边的字母化成这边这个小的字母。

    #include<bits/stdc++.h>
    #include<vector>
    #include<map>
    #include<queue>
    #define LL long long
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    using namespace std;
    char s[100005];
    int main()
    {
        scanf("%s", s);
        int len = strlen(s);
        int n = len/2;
        for(int i = 0,j = len-1;i < n;i++,j--)
        {
            if(s[i] < s[j])
                s[j] = s[i];
            else
                s[i] = s[j];
        }
        for(int i = 0;i < len;i++)
            printf("%c", s[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    每天学一点MATLAB函数——文件编程函数
    每天学一点MATLAB函数——软件操作函数(1)
    C# 杂记
    ActiveX控件注册与反注册
    First Java Graphic Program
    判断式
    两个仿函数示例
    STL文件的读取与显示
    SQLite数据库(一)
    机器学习--如何理解Accuracy, Precision, Recall, F1 score
  • 原文地址:https://www.cnblogs.com/Mamba0Z/p/11959155.html
Copyright © 2020-2023  润新知