算法习题---3.11换抵挡装置(UVa1588)

一:题目

给你连个长度分别为n1,n2且每列高度只为1或2的长条,然后将他们拼在一起,高度不能超过3,问他们拼在一起的最短长度

二:实现思路

1.获取主动轮和从动轮的数据。
2.主动轮不动,从动轮从左向右开始进行卡位,不断更新卡位成功(最大高度不超过3)时的最小长度
3.注意:当我们在某一时刻的长度若是小于等于主/从动轮的长度时,不向下判断

三:测试数据

输入数据

2112112112
2212112
12121212
21212121
2211221122
21212

输出数据

10
8
15

四:模拟卡位

(一)主动轮+从动轮:最小长度两者之和17

2112112112
2212112

(二)开始第一步:高度超过3,失败

(三)第二步:卡位成功,最小长度变为15

(四)第三步:卡位成功,最小长度14

(五)第四步:卡位失败(高度超过3),不进行更新

(六)第五步:卡位成功,最小长度12

(七)第六步:卡位失败

(八)第七步:卡位失败

(九)第九步:卡位成功,最小长度为10,等于主动轮长度,所以不进行下面的卡位,直接跳出

五:代码实现

void test36()
{
    FILE* fi = freopen("data.in", "r", stdin);
    FILE* fo = freopen("data.out", "w", stdout);

    int Mater[100];    //主齿轮
    int Drive[100];    //从齿轮

    int ch,Min_Len,Max_Len;

    int M_l, D_l;
    int count = 3;

    while (!feof(fi))
    {
        memset(Mater, 0, sizeof(Mater));
        memset(Drive, 0, sizeof(Drive));
        M_l = D_l = 0;  //M_l是记录主动轮长度,D_l记录从动轮长度//开始读取主动轮数据
        while ((ch = getchar()) != '
' && ch != EOF)
        {
            Mater[M_l++]=ch-'0';
        }

        //开始读取从动轮数据
        while ((ch = getchar()) != '
' && ch != EOF)    //EOF是-1 字符串结束是''--0
        {
            Drive[D_l++] = ch - '0';
        }

        //不能根据长度卡位
        
        //从动轮开始从尾部与主动轮头部卡位,依次得出最小距离
        Min_Len = Max_Len = D_l + M_l;    //初始是两个没有卡位好  D_l+M_l是初值,每当卡位一个就在基础上减一
        //从动轮开始右移

//开始卡位主动轮 从第一个开始到最右边全部出去
        int i, j, flag;
        for (i = 0; i < Max_Len; i++)
        {
            //向左验证
            flag = 1;
            for (j = 0; j <= i; j++)        
            {
                if (Drive[D_l - 1 - j] + Mater[i - j]>3)    //从动轮的右边开始向左进行验证,若是从动轮高度加上主动轮高度>3-->卡位失败
                {
                    flag = 0;
                    break;  //卡位失败,不向后进行验证了
                }
            }

            if (flag)    //卡位成功
            {
                if (j<=M_l)    //从动轮在主动轮左侧
                {
                    if (j >= D_l)    //全部卡入,是最小  
                    {
                        Min_Len = M_l;
                        break;
                    }
                    else  //没有卡完,只有部分重合,还有一部分在外面未进入
                        if (Min_Len > Max_Len - j)
                            Min_Len = Max_Len - j;
                }
                else //从动轮在主动轮右侧
                    if (Min_Len > Max_Len - (D_l - i + M_l - 1))
                        Min_Len = Max_Len - (D_l - i + M_l - 1);
            }
        }
        printf("%d
", Min_Len);
    }

    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
}
去掉括号,空格,注释,缩减声明(全部放入一行)...操作以后。代码行数会减少不少(但是没必要)
原文地址:https://www.cnblogs.com/ssyfj/p/10811589.html