zoukankan      html  css  js  c++  java
  • UVa 1588 换抵挡装置

    前言

    题目

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

    思路

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

    实现

    
    //习题3-11 换抵挡装置
    void caculate17() {
        char n1[1000], n2[1000];
        while (scanf("%s
    %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
    ", min);
        }
    }
    
    // 题目同上
    void caculate18() {
        char n1[1000], n2[1000];
        while (scanf("%s
    %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
    ", maxLen);
            }
            else {
                printf("%d
    ", min);
            }
        }
    }
    
    // 大神思路,简单高效
    void caculate19() {
        char s1[128], s2[128];
        while (scanf("%s
    %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
    ", ret);
        }
    }
    
    
    int main() {
        caculate18();
        return 0;
    }
    
    

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

  • 相关阅读:
    动态规划——Best Time to Buy and Sell Stock IV
    动态规划——Split Array Largest Sum
    动态规划——Burst Ballons
    动态规划——Best Time to Buy and Sell Stock III
    动态规划——Edit Distance
    动态规划——Longest Valid Parentheses
    动态规划——Valid Permutations for DI Sequence
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
  • 原文地址:https://www.cnblogs.com/George1994/p/6542380.html
Copyright © 2011-2022 走看看