• 湖南师范大学第四届大学生计算机程序设计竞赛 记录下水果的三题。。。


    昨晚12点闲着打开oj近期的比赛,发现了湖师大的校赛(?),四级刚考完,好久没刷题的赶脚,于是今天起来就准备刷了,想拉zyf来开黑那家伙竟然睡得像懒猪一样睡了一早上。。。

    算了,我一个人水一水就好了。。。

    开赛后题目满眼的中文,良心哪。。给我的第一感觉就是很水,因为里面有几个很熟悉的名词,最长公共子序列、汉诺塔什么的。。。


    由于前段时间刚学过LCS,于是就先看C题最长公共子序列了,题目也没怎么看,看过样例后就觉得是很水的,手敲了一遍当作练手,调过后提交上去,超时了。。。然后才发现,那题没什么人做,大家都在刷D题。。。

    看来C还是有点难度的,至少不是一眼题。。。于是返回看题目,原来是给定的二个序列没有重复的元素,如果数据大点,原来那个n*n的算法肯定超时了。。。


    然后YY了一会C发现头脑迟钝想不出来,发了会呆转战D题。。。

    D题是超级大水题,于是水掉了。。。(由于重定向没去掉,WA了一次。。)(代码找不到了T T)


    然后C题还是没思路,看很多人过了的E题,同水题,画图题,本来以为能用bfs做,于是写出来发现没旋转对,于是重新写,水果了。。。

    代码:

    #include <cstdio>
    #include <cstring>
    
    int snack[12][12];
    int fill, n, d[4][2] = {0,1, 1,0, 0,-1, -1,0};
    int main() {
        freopen("in", "r", stdin);
        while (scanf("%d", &n) != EOF) {
            memset(snack, 0, sizeof(snack));
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                    snack[i][j] = -1;
            int x = 1, y = 1, a = 0;
            fill = 1;
            while (fill != n * n + 1) {
                snack[x][y] = fill++;
                if (snack[x + d[a][0]][y + d[a][1]] != -1)
                    a = (a + 1) % 4;
                x += d[a][0];
                y += d[a][1];
            }
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++)
                    printf("%3d", snack[i][j]);
                printf("
    ");
            }
        }
        return 0;
    }



    C题还是没思路,看A题,是英文。。。发现是变形的最短路,感觉和以前的一类最小生成树很像,最近在练最小生成树,本来还挺高兴可以练手下,发现变形太厉害,最短路也不是很熟,于是不会了。。。


    回头发呆,继续YY C题,题目说不会重复,总是想到n*n以上复杂度的算法。。。

    网上找LCS的优化,发现都是n*n,记起LIS的话就有n*logn的算法优化,于是YY出一个方法,把LCS转化为LIS然后用优化算法就行了。。。

    接下来的问题就是YY转化的办法了。。。

    思路为:记录第一组各个数字的位置,读取第二组,把第一组出现的相同数字的位置放入序列,没出现就不放。。。然后就转成LIS题目了。。。用上吉大的模版然后就A了。

    证明就另开一篇吧。。。

    湖师大的oj不能看提交的代码,我本地又覆盖掉了。。。T T

    于是重敲了一遍:

    #include <cstdio>
    #include <cstring>
    const int maxn = 100001;
    int f[maxn], d[maxn];
    //LIS模版。。。
    int bsearch(const int *f, int size, const int &a) { 
        int  l=0, r=size-1; 
        while( l <= r ){ 
            int  mid = (l+r)/2; 
      if( a > f[mid-1] && a <= f[mid] ) return mid;
            else if( a < f[mid] ) r = mid-1; 
            else l = mid+1; 
        } 
    } 
    int LIS(const int *a, const int &n){ 
     int  i, j, size = 1; 
     f[0] = a[0]; d[0] = 1; 
     for( i=1; i < n; ++i ){ 
         if( a[i] <= f[0] ) j = 0;
     else if( a[i] > f[size-1] ) j = size++;
      else j = bsearch(f, size, a[i]); 
      f[j] = a[i]; d[i] = j+1; 
     } 
     return size; 
    } 
    
    int main() {
    //    freopen("in", "r", stdin);
        int rec[maxn], lis[maxn], n, tmp;
        while (scanf("%d", &n) && n) {
            int cnt = 0;
            memset(rec, -1, sizeof(rec));
            for (int i = 1; i <= n; i++) {
                scanf("%d", &tmp);
                rec[tmp] = i;                  //存放位置
            }
            for (int i = 1; i <= n; i++) {
                scanf("%d", &tmp);
                if (rec[tmp] != -1)
                    lis[cnt++] = rec[tmp];      //生成LIS
            }
            printf("%d
    ", LIS(lis, cnt));
        }
        return 0;
    }


    然后作为这题看了下B题,因为很多人A了,感觉得用并查集做,做了一半,肚子饿了,叫餐还叫不过来,于是不做了。。。感觉有更好的方法,而且还不知道会不会超时。。。坐等大神了。。

    看其他几题,没几个人A,看了下题目,都改得很奇怪。。。于是就到此了,吃饭休息了。。。


    这次比赛感觉还好,YY出了一题感觉真棒,坐等大神牛逼算法了。。。

  • 相关阅读:
    170110-学习MoveIt!
    12.29-ros-gazebo高级
    12.27-ros-gazebo基础
    4.9-Simulation in gazebo or webots
    6.28-机器人模拟器Gazebo基础
    4.8-URDF in ROS
    Win32双缓冲画图原理
    Win32 计时器
    最简化的DirectX 11开发环境的配置 VS2010
    VS2010 C++编译报错LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/java20130723/p/3212136.html
Copyright © 2020-2023  润新知