• 4.21小练


    Mutual Training for Wannafly Union #3 & 4

    我不知道我以后还记不记得补题。。。我只能尽量当天睡觉前能补多少就补多少,时间总是不够用,脑子更不够用orz

    题目链接:https://vjudge.net/contest/159576#overview

    A - Dungeon Trap     [ UVALive – 7220 ]  【最短路bfs】

    //yy:练题时都没看这题,看题目就以为很难。。。晚上补 的时候发现居然是最短路,奥妙重重。。。

    题意:0表示障碍,要将非0数转化成0(会花费这个数的值)使得A和B不连通(该题连通为四连通),问最大花费多少。

    看着题解做的,枚举最后一个放置障碍的点,则ans=max(ans,sum-(从A到这个点的距离+从B到这个点的距离-2*这个点的权值));

    //补题:AC  by  lyy:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int N = 105;
    const int inf = 0x3f3f3f3f;
    int n, m;
    int sum;
    int dx[] = {1,0,-1,0};
    int dy[] = {0,1,0,-1};
    char s[N][N];
    int d[N][N][2];
    int ans;
    int ax, ay, bx, by;
    bool check(int x, int y) {
        if(x < 0 || x >= n || y < 0 || y >= m)
            return false;
        if(s[x][y] == '0')
            return false;
        return true;
    }
    struct node {
        int x, y;
    };
    void bfs(int x, int y, int id) {
        queue<node> q;
        d[x][y][id] = 0;
        q.push(node{x, y});
        while(!q.empty()) {
            node t = q.front(); q.pop();
            for(int i = 0; i < 4; ++i) {
                int xx = t.x + dx[i];
                int yy = t.y + dy[i];
                int w = s[xx][yy]-'0';
                if(check(xx, yy)) {
                    if(d[xx][yy][id] > d[t.x][t.y][id] + w) {
                        d[xx][yy][id] = d[t.x][t.y][id] + w;
                        q.push(node{xx, yy});
                    }
                }
            }
        }
    }
    int main(){
        int t;
        int i, j, k;
        scanf("%d",&t);
        for(k = 1; k <= t; ++k) {
            CLR(d, inf);
            scanf("%d%d", &n, &m);
            sum = 0;
            for(i = 0; i < n; ++i) {
                scanf("%s", s[i]);
                for(j = 0 ; j < m; ++j) {
                    if(s[i][j] == 'A') {
                        ax = i; ay = j;
                    }
                    else if(s[i][j] == 'B') {
                        bx = i; by = j;
                    }
                    else {
                        sum += s[i][j] - '0';
                    }
                }
            }
            bfs(ax, ay, 0);
            bfs(bx, by, 1);
            ans = 0;
            for(i = 0; i < n; ++i) {
                for(j = 0; j < m; ++j) {
                    if(s[i][j] >= '1' && s[i][j] <= '9') {
                        if(d[i][j][0] != inf && d[i][j][1] != inf) {
                            int c = s[i][j] - '0';
                            ans = max(ans, sum-d[i][j][0]-d[i][j][1]+2*c);
                        ]
                    }
                }
            }
            printf("Case #%d: %d
    ", k, ans);
        }
        return 0;
    }

    B - Pigeonhole Tower   [ SPOJ – PHT ] 【二分】

    题意:求用n根木棒能搭出多少层

    第一层3根,第二层5,第三层7.。。。2*n+1.。。。。。。二分数量

    //AC  by  lwq:

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    long long int q[1000000]; 
    int main()
    {
        int T;
        scanf("%d",&T);
        q[1]=3;
        int t=0;
        for(int i=2;i<=1000000;i++)
        {
            q[i]=q[i-1]+2*i+1;
        }
        while(T--)
        {
            t++;
            long long int n;
            scanf("%lld",&n);
            long long int L=1;
            long long int R=1000000;
            long long int MID=(L+R)/2;
            while(L+1<R)
            {
                if(n>=q[MID])
                {
                    L=MID;
                }
                else
                R=MID;
                
                MID=(L+R)/2;
            }
            if(n<3)
            MID=0;
            printf("Case %d: %lld
    ",t,MID);
        //    printf("%")
        }
        return 0;
    }

    C - Interesting Numbers  [ SPOJ – INUM ]  【二分】

    题意:求分别有几对数满足差值绝对值最大和最小。

    //AC  by  kn:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <climits>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 100;
    ll a[maxn];
    
    int main()
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; ++i) {
            cin >> a[i];
        }
        ll mi = LONG_LONG_MAX;
        ll ma = LONG_LONG_MIN;
        sort(a, a + n);
        for(int i = 1; i < n; ++i) {
            mi = min(mi, a[i] - a[i - 1]);
        }
        ma = a[n - 1] - a[0];
        ll ans_mi = 0;
        ll ans_ma = 0;
        for(int i = 0; i < n; ++i) {
            ans_mi += (upper_bound(a + i + 1, a + n, a[i] + mi) - lower_bound(a + i + 1, a + n, a[i] + mi));
            ans_ma += (upper_bound(a + i + 1, a + n, a[i] + ma) - lower_bound(a + i + 1, a + n, a[i] + ma));
        }
        //cout << mi << " " << ma << endl;
        cout << ans_mi << " " << ans_ma << endl;
        return 0;
    }
    
    /*
    5
    0 0 2 0 0
    */

    D – SubXor   [SPOJ – SUBXOR]

    //yy:讨论了一会儿,我猜要用前缀树什么的,要不然超时,,然后大家都不会数据结构,然后就没有然后了orz,改天再补。。。

    E – Guards   [UVALive – 5813]

    //yy:就看懂了题意,没想出思路orz,很好玩,看题目发现构成一个矩形时就是一个集合,其他又是一个集合,然后想搜索,不会,也想不出怎么安排棋子;想了找规律,感觉也找不到;想了图论,也没想出什么,毕竟图论我感觉自己连基本概念都很多不知道;想了DP然后就不敢再想了。。。。放弃orz,改天补。。。

    F - Extremely Lagged Fibonacci   [SPOJ – EXLAGFIB]

    //yy:感觉太数学,再次放弃,害怕orz

    G - Smile House   [CodeForces – 147B]

    //yy:我看完这题突然想到floyd,dp之类的,但是不知道具体怎么处理,又放弃了orz,改天再补

    H - Renting Bikes   [CodeForces – 363D]  【贪心,二分】

    题意:已知每辆车的价格和人有的钱数和共享资金,每人最多买一辆车,问最多能买多少车以及私人花费的最多钱数。

    题解:二分买车的数量,用最有钱的mid个人买最便宜的mid辆车。

    //yy:二分折腾了好久orz结果最后细节没处理好一直WA,,二分求和时忘记改long long了。。

    补题:AC  by  lyy:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int N = 1e5+5;
    int n, m, k;
    int a[N], b[N];
    bool cmp(int x, int y) { return x > y; }
    int main(){
        int i, j;
        scanf("%d%d%d", &n, &m, &k);
        for(i = 0; i < n; ++i) scanf("%d", &a[i]);//人有的钱
        for(i = 0; i < m; ++i) scanf("%d", &b[i]);//车的价格
        sort(a, a+n, cmp);
        sort(b, b+m);
        int l = 0, r = min(n, m);
        while(l < r) {//二分买车的数量
            int mid = (l + r + 1) >> 1;
            ll s = 0;
            for(int i = 0; i < mid; ++i) {
                if(a[i] < b[mid-1-i]) {
                    s += b[mid-1-i] - a[i];
                }
            }
            if(s > k) r = mid-1;
            else l = mid;
        }
        printf("%d ", r);
        ll s = 0;
        for(i = 0; i < r; ++i) {
            s += b[i];
        }
        s -= k;
        if(s < 0) s = 0;
        printf("%lld
    ", s);
        return 0;
    }

    I - Greg's Workout  [CodeForces – 255A]  【水题】

    //AC  by  lyy:我觉得自己好水啊、、、

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int N = 1e5;
    const int mod = 1e9+7;
    int a[30];
    int main() {
        int n;
        scanf("%d", &n);
        int i, j;
        int x = 0, y = 0, z = 0;
        for(i = 0; i < n; ++i) {
            scanf("%d", &a[i]);
            if(i % 3 == 0) {x += a[i];}
            else if(i % 3 == 1) {y+=a[i];}
            else z+=a[i];
        }
        if(x >= y ) {
            printf("%s
    ", x > z ? "chest" : "back");
        }
        else printf("%s
    ", y > z ?  "biceps" : "back");
        return 0;
    }

    J - MUH and Cube Walls  [CodeForces – 471D]   【KMP】

    题解:将幅度记录(就是相邻两数的差值),再KMP。

    //AC  by  lyy:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int N = 2e5+5;
    const int mod = 1e9+7;
    double eps = 1e-8;
    int n, m;
    int ans;
    int a[N], b[N];
    
    int nex[N];
    void Next() {
        int i, j;
        j = nex[0] = -1;
        i = 0;
        while(i < m) {
            while(-1 != j && b[i] != b[j])
                j = nex[j];
            nex[++i] = ++j;
        }
    }
    void kmp(){
        int i = 0, j = 0;
        Next();
        while(i < n){
            if(j == -1 || a[i] == b[j]){
                i++; j++;
            }
            else
                j = nex[j];
            if(j == m) {
                ans++;
            }
        }
    }
    
    int main(){
        int i, j;
        scanf("%d%d", &n, &m);
        for(i = 0; i < n; ++i) scanf("%d", &a[i]);
        for(i = 0; i < m; ++i) scanf("%d", &b[i]);
        if(m == 1) { printf("%d
    ", n); return 0; }
    
        for(i = 0; i < n-1; ++i) {
            a[i] = a[i+1] - a[i];
        }
        for(j = 0; j < m-1; ++j) {
            b[j] = b[j+1] - b[j];
        }
        ans = 0;
        --n, --m;
        kmp();
        printf("%d
    ", ans);
        return 0;
    }

    K – Reclamation   [CodeForces – 325D]   【并查集】

    //yy:kn说这题他去年听学姐讲过但是没在意听,然后开始想思路,说先在右边加上最左边一列,再在两边设两个源点并分别把两边的格子连接,然后每放一个障碍就检查其周围八个格子是否有跟两个源点连接,如果有就不能放这个障碍……总之就是,只要障碍左右都连通了,那么圆柱的上顶和下底就会不连通,就不能放这个障碍,,然后他敲了发并查集没过,然后我们又挂了orz

    L - Crazy Town   [CodeForces – 499C]   【几何】

    题意:有很多直线会把平面划分成很多块,给出直线方程的系数,起点和终点坐标,问最少走过几块可以从起点到终点

    题解:分别把起点和终点代入每个直线方程,判断两点是否在直线两侧,是的话答案加一。

    //yy:把long long改成了double就过了、、水题我总能以各种姿势先WA一下。。

    AC  by  lyy:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int N = 1e5;
    const int mod = 1e9+7;
    double eps = 1e-8;
    double x1, y1, x2, y2;
    int main() {
        int n;
        scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
        scanf("%d", &n);
        int ans = 0;
        while(n--) {
            double a, b, c;
            scanf("%lf%lf%lf", &a, &b, &c);
            if((a*x1+b*y1+c) * (a*x2+b*y2+c) < eps)
                ans++;
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    在线程中更新UI
    Panel容器
    ImageList组件
    PrograssBar控件
    PictureBox控件
    GroupBox控件
    Timer控件Forms.Timer\System.Timers.Timer\System.Threading.Timer
    DataGridView控件1——手动添加数据,遍历数据
    SplitContainer控件
    Git理论知识
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/6746680.html
Copyright © 2020-2023  润新知