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,应该是只过了部分的测试用例,但我不知道怎么改了~

  • 相关阅读:
    VB几种函数参数传递方法,Variant,数组,Optional,ParamArray
    一些 Windows 系统不常见的 鼠标光标常数
    加载MSCOMCTL.OCX错误处理的几个关键
    如何快速掌握一门技术
    《将博客搬至CSDN》
    日期小demo
    iOS崩溃解决记录
    Swift基础语法
    iOS端APP切图命名规范大全
    PHP案例:学生信息管理系统
  • 原文地址:https://www.cnblogs.com/George1994/p/6542380.html
Copyright © 2011-2022 走看看