zoukankan      html  css  js  c++  java
  • hdu_4300, hdu_4302, hdu_4308

    这是12年多校的第一场

    当时在做信安大赛,没有时间做

    这两天补过来了

    只会三题= =、而且还做了很久。。还是弱到爆啊

    4300题就是一个简单的字符串模拟,不知道为什么两位队友为什么做了那么久了。。。

    第一个串长26,相当于一个key了

    第二个串是明文+密文,密文长度可能为0,前面一半绝对是明文

    然后要你找出最短的明文

    我就直接模拟过了,感觉要调BUG好久,不过真的就那么一搞就AC了

    View Code
    #include <cstdio>
    #include <cstring>
    #include <map>
    #include <string>
    #include <iostream>
    using namespace std;
    
    string s1, s2;
    map < char, char > m;
    int main()
    {
        int tcase;
        scanf("%d", &tcase);
        while(tcase --)
        {
            cin>>s1>>s2;
            for(int i = 0, j = 'a'; s1[i]; i ++)
            {
                m[s1[i]] = j;
                //if(j == 'q') cout<<s1[i]<<endl;
                j ++;
            }
            if(s2.length() == 1)
            {
                printf("%c%c\n", s2[0], m[s2[0]]);
                continue;
            }
            int pos1 = 0;
            int pos2 = 0;
            int ans = s2.length();
            for(int i = (s2.length() + 1) / 2; i < s2.length(); i ++)
            {
                if(m[s2[0]] == s2[i])
                {
                    pos1 = 1;
                    int j;
                    for(j = i + 1; s2[j]; j ++, pos1 ++)
                    {
                        if(m[ s2[pos1] ] != s2[j])
                        {
                            break;
                        }
                    }
                    if(j < s2.length())
                    {
                        i = j;
                    }
                    else
                    {
                        ans = i;
                        break;
                    }
                }
            }
            for(int i = 0; i < ans; i ++)
            printf("%c", s2[i]);
            for(int i = 0; i < ans; i ++)
            printf("%c", m[s2[i]]);
            puts("");
        }
        return 0;
    }

    4302题是一个线段树了

    ZY给我讲的题,我没有看题

    题意大概是:L表示总长,n表示数据组数,0后面接一数字表示在该位置放蛋糕,1表示吃掉离    他最近的蛋糕,最后求总长

    网上的解题报告是用的模拟的,我用的线段树,而且出了一大堆错,最后就看着解题报告的标程    AC了= =

    View Code
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    
    const int maxn = 100000 + 10;
    int sum[maxn<<2];
    int max_[maxn<<2];
    int min_[maxn<<2];
    const int inf = ~0U>>1;
    
    void build(int l, int r, int rt){
        //if(l > r)
        //return;
        sum[rt] = 0;
        max_[rt] = -inf;
        min_[rt] = inf;
        if(l == r){
            return;
        }
        int m = l + r >> 1;
        build(lson);
        build(rson);
    }
    void update(int num, int e, int l, int r, int rt){
        if( num < l || num > r) return;
        if(l == r){
            sum[rt] += e;
            if(sum[rt])
              max_[rt] = min_[rt] = num;
            else{
                max_[rt] = -inf;
                min_[rt] = inf;
            }
            return;
        }
        int m = l + r >> 1;
        update(num, e, lson);
        update(num, e, rson);
        max_[rt] = max(max_[rt<<1], max_[rt<<1|1]);
        min_[rt] = min(min_[rt<<1], min_[rt<<1|1]);
    }
    int find_max(int a, int b, int l, int r, int rt){
        if(b < l || a > r  ) return -inf;
        if(a <= l && b >= r)
          return max_[rt];
        int m = l + r >> 1;
        return max(find_max(a, b, lson), find_max(a, b, rson));
    }
    int find_min(int a, int b, int l, int r, int rt){
        if(b < l || a > r  ) return inf;
        if(a <= l && b >= r)
          return min_[rt];
        int m = l + r >> 1;
        return min(find_min(a, b, lson), find_min(a, b, rson));
    }
    
    int main(){
        int tcase;
        int z = 1;
        scanf("%d", &tcase);
        while(tcase --){
            int L, n;
            scanf("%d%d", &L, &n);
            build(0, L, 1);
            int now = 0;
            int ans = 0;
            int dir = 1;
            //puts("asdf");
            while(n --){
                //printf("n  %d", n   );
                int a, b;
                scanf("%d", &a);
                if(a == 0){
                    scanf("%d", &b);
                    update(b, 1, 0, L, 1);
                    continue;
                }
                int l = find_max(0, now, 0, L, 1);
                int r = find_min(now, L, 0, L, 1);
                //printf("---  %d  %d\n", l, r);
                if(l <= -inf && r >= inf)
                  continue;
                else
                  if(l <= -inf)
                    ans += r - now, now = r, dir = 1;
                  else
                    if(r >= inf)
                      ans += now - l, now = l, dir = 0;
                    else
                      if(now - l < r - now)
                        ans += now - l, now = l, dir = 0;
                      else
                        if(now - l > r - now)
                          ans += r - now, now = r, dir = 1;
                        else
                          if(dir)
                            ans += r - now, now = r, dir = 1;
                          else
                            ans += now - l, now = l, dir = 0;
                            //printf("ans:   %d\n", ans);
                update(now, -1, 0, L, 1);
            }
            printf("Case %d: %d\n", z++, ans);
        }
        return 0;
    }

    4308题最坑人了

    昨天做的时候,把P全连通给看错了

    我以为是走到一个P然后隔一格跳过去

    太想当然了

    这样的话,如果P全连通,最短路来做确实方便

    不过我一开始就用的BFS

    所以最后还是在BFS上改的

    一走到P然后就把所有的P加入到队列当中

    用的优先队列

    不知道为什么过不了==

    最后看蛋蛋哥队友的代码

    改了一下写法,也就是在完全BFS之后再返回一个值了

    这样就行了,这个真的学习了Orz

    View Code
    #include<cstdio>
    #include<queue>
    #include<cstring>
    
    using namespace std;
    struct point{
        int x, y;
        int sum;
    };
    bool flag[5000 + 10][5000 + 10];
    int r, c, cost;
    char map[5000 + 10][5000 + 10];
    int dir[4][2] = {
        1, 0,
        -1, 0,
        0, 1,
        0, -1
    };
    int count_;
    int xx[5000 + 10];
    int yy[5000 + 10];
    int bfs(point start, point end){
        queue < point > q;
        q.push(start);
        int ans = -1;
        int flag1 = 0;
        while(!q.empty()){
            point tmp = q.front();
            q.pop();
            for(int i = 0; i < 4; i ++){
                int x = tmp.x + dir[i][0];
                int y = tmp.y + dir[i][1];
                if(x < 0 || x >= r || y < 0 || y >= c){
                    continue;
                }
                if(x == end.x && y == end.y){
                    //return tmp.sum;
                    if(tmp.sum < ans || ans == -1)
                        ans = tmp.sum;
                    continue;
                }
                if(map[x][y] == '#')
                  continue;
                if(flag[x][y] == 1)
                  continue;
                point now;
                now.x = x;
                now.y = y;
                now.sum = tmp.sum;
                if(map[x][y] == '*'){
                    flag[x][y] = 1;
                    now.sum = tmp.sum + cost;
                    q.push(now);
                }
                if(map[x][y] == 'P'){/*
                    if(y + 2 < c && map[x][y + 2] == 'P'){
                        flag[x][y + 2] = 1;
                        now.y = y + 2;
                        q.push(now);
                    }
                    if(y - 2 >= 0 && map[x][y - 2] == 'P'){
                        flag[x][y - 2] = 1;
                        now.y = y - 2;
                        q.push(now);
                    }
                    if(x + 2 < r && map[x + 2][y] == 'P'){
                        flag[x + 2][y] = 1;
                        now.x = x + 2;
                        q.push(now);
                    }
                    if(x - 2 >= 0 && map[x - 2][y] == 'P'){
                        flag[x - 2][y] = 1;
                        now.x = x - 2;
                        q.push(now);
                    }*/
                    if(flag1 == 1) continue;
                    flag1 = 1;
                    for(int j = 0; j < count_; j ++){
                        now.x = xx[j];
                        now.y = yy[j];
                        flag[now.x][now.y] = 1;
                        q.push(now);
                    }
                }
            }
        }
        //return -1;
        return ans;
    }
    int main(){
        while(~scanf("%d%d%d", &r, &c, &cost)){
            for(int i = 0; i < r; i ++){
                scanf("%s", map[i]);
            }
            point start, end;
            memset(flag, 0, sizeof(flag));
            count_ = 0;
            for(int i = 0; i < r; i ++){
                for(int j = 0; j < c; j ++){
                    if(map[i][j] == 'Y'){
                        start.x = i;
                        start.y = j;
                        flag[i][j] = 1;
                    }
                    if(map[i][j] == 'C'){
                        end.x = i;
                        end.y = j;
                    }
                    if(map[i][j] == 'P'){
                        xx[count_] = i;
                        yy[count_ ++] = j;
                    }
                }
            }
            start.sum = 0;
            int f = bfs(start, end);
            if(f == -1)
              puts("Damn teoy!");
            else
              printf("%d\n", f);
        }
        return 0;
    }

    就记到这里了,下午多校第二场,求RP了

  • 相关阅读:
    前端博客收集
    Oracle 数据库性能调优
    vue解决跨域问题
    IIS相关问题及解决方案
    《软件测试工程师》学习笔记
    Matlab学习笔记(一)
    排序算法及分析
    Silverlight学习笔记——跨域调用
    Matlab学习笔记(三)
    C#的一些必备技术
  • 原文地址:https://www.cnblogs.com/louzhang/p/2609693.html
Copyright © 2011-2022 走看看