UVa 1588 换抵挡装置

前言

题目

大意是说,两个槽能够插在一起,并保证每一列的高度不高于3,保证最短长度。

思路

思路很简单,取短字符串遍历长字符串的每一个位置,纪录下位置,并取最短即可。

实现


//习题3-11 换抵挡装置
void caculate17() {
    char n1[1000], n2[1000];
    while (scanf("%s\n%s", n1, n2) != EOF) {
        char *min_arr, *max_arr;
        if (strlen(n1) < strlen(n2)) {
            min_arr = n1;
            max_arr = n2;
        }
        else {
            min_arr = n2;
            max_arr = n1;
        }

        int minLen = (int)strlen(min_arr);
        int maxLen = (int)strlen(max_arr);

        int min = minLen + maxLen;
        // 从最长数字的左边开始对齐
        for (int j = 0; j < maxLen; j++) {
            int j_temp = j;
            int result = 1;
            for (int i = minLen-1; i >= 0 && j_temp >= 0; i--) {
                int sum = (min_arr[i] - '0') + (max_arr[j_temp] - '0');
                if (sum > 3) {
                    result = 0;
                    break;
                }

                j_temp--;
            }

            if (result) {
                int temp = 0;
                if (j >= strlen(min_arr)-1) {
                    temp = maxLen;
                }
                else {
                    temp = minLen + maxLen - (j + 1);
                }
                if (temp < min) {
                    min = temp;
                }
            }
        }

        if (strlen(min_arr) != strlen(max_arr)) {
            // 从最大数字的右边开始对齐
            for (int j = maxLen - minLen; j < maxLen; j++) {
                int j_temp = j;
                int result = 1;
                for (int i = 0; i < minLen && j_temp < maxLen; i++) {
                    int sum = (min_arr[i] - '0') + (max_arr[j_temp] - '0');
                    if (sum > 3) {
                        result = 0;
                        break;
                    }

                    j_temp++;
                }

                if (result) {
                    int temp = 0;
                    if (j == maxLen - minLen) {
                        temp = maxLen;
                    }
                    else {
                        temp = minLen + maxLen - (maxLen - j);
                    }
                    if (temp < min) {
                        min = temp;
                    }
                }
            }
        }

        printf("%d\n", min);
    }
}

// 题目同上
void caculate18() {
    char n1[1000], n2[1000];
    while (scanf("%s\n%s", n1, n2) != EOF) {
        char *min_arr, *max_arr;
        if (strlen(n1) < strlen(n2)) {
            min_arr = n1;
            max_arr = n2;
        } else {
            min_arr = n2;
            max_arr = n1;
        }

        int maxLen = (int)strlen(max_arr);
        int minLen = (int)strlen(min_arr);

        int min = maxLen + minLen;
        int result = 0;
        for (int i = -minLen; i < maxLen + minLen; i++) {
            int ok = 1;
            // 判断
            for (int j = 0; j < minLen; j++) {
                // 重合部分
                if (i+j >= 0 && i+j < maxLen) {
                    if ((max_arr[i + j] - '0') + (min_arr[j] - '0') > 3) {
                        ok = 0;
                        break;
                    }
                }
            }

            // 短字符串在左边,部分重合
            if (ok && i < 0) {
                int temp = -i + maxLen; //-i代表左边的距离,移动距离则是重合部分
                if (temp < min) {
                    min = temp;
                }
            }

            //短字符串在右边,部分重合
            if (ok && i > maxLen - minLen) {
                int temp = i + minLen; //这里的i则代表移动距离,没有包括重叠的部分
                if (temp < min) {
                    min = temp;
                }
            }

            // 完全重合(最优解)
            if (ok && i >= 0 && i + minLen <= maxLen) {
                result = 1;
                break;
            }
        }

        if (result) {
            printf("%d\n", maxLen);
        }
        else {
            printf("%d\n", min);
        }
    }
}

// 大神思路,简单高效
void caculate19() {
    char s1[128], s2[128];
    while (scanf("%s\n%s", s1, s2) == 2) {
        int max_len = strlen(s1), min_len = strlen(s2);
        int ret = min_len + max_len;

        // 从左到右
        for (int i = -min_len; i < max_len; i++) {
            int ok = 1;
            for (int j = 0; j < min_len && ok; j++) {
                if (i + j >= 0 && i + j < max_len) {
                    ok &= s1[i+j] - '0'  + s2[j] - '0' <= 3;
                }
            }

            if (ok) {
                // 如果短字符串在左边或者重合的话,则为-i + max_len
                // 如果短字符串在右边的话,则为i + min_len
                ret = min(ret, max(max_len, i + min_len) - min(i, 0)); //太棒了!
            }
        }

        printf("%d\n", ret);
    }
}


int main() {
    caculate18();
    return 0;
}

呃,我的实现是第一种,没ac,应该是只过了部分的测试用例,但我不知道怎么改了~

转载于:https://www.cnblogs.com/George1994/p/6542380.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值