换抵挡装置(按位运算符的运用)

给出两个长度分别为n1,n2(n1 + n2 <=32)且每列高度只为1或2的长条(保证高度为1的地方水平上一致)。需要将它们放入一个高度为3的容器长度,问能够容纳它们的最短容器长度

换抵挡装置(按位运算符的运用)_第1张图片

用手画的

本来是n1,n2 <= 100的,但是我想用一下按位运算符,就稍微改了一下题目

也可以数组模拟,这样可以满足原本的条件

输入格式:

第一行为两个整数,代表n1,n2

第二行有n1个数,为1或者2,代表列高

第三行有n2个数,为1或者2,代表列高

输出格式:

一个整数,代表最短容器长度

(注意:输入时长条的最下层是填满的,即如果要组装,需要将其中一个长条反转。且长条可以左右翻转(那前一句就没影响了,反正都要试一下))

代码如下:

#include
int input(int length);
int roll(int l, int length);
int getmin(int l1, int l2, int n1, int n2);

int main(void)
{
    int n1, n2, min = 0, tmp;
    scanf("%d%d", &n1, &n2);
    int l1 = input(n1), l2 = input(n2);//list
    min = getmin(l1, l2, n1, n2);

    l1 = roll(l1, n1);
    tmp = getmin(l1, l2, n1, n2);
    min = (tmp < min) ? tmp : min;

    l2 = roll(l2, n2);
    tmp = getmin(l1, l2, n1, n2);
    min = (tmp < min) ? tmp : min;

    l1 = roll(l1, n1);
    tmp = getmin(l1, l2, n1, n2);
    min = (tmp < min) ? tmp : min;

    printf("%d", min);

    return 0;
}
int input(int length)
{
    int tmp = 0;
    for(int i = 0, j; i < length; i++)
    {
        scanf("%d", &j);
        tmp |= --j;
        tmp <<= 1;
    }
    return tmp >> 1;
}
int roll(int l, int length)
{
    int i = 1, j = 1;
    for(int x = 1; x < length; x++)
        j <<= 1;
    for(; i < j; i <<= 1, j >>= 1)
    {
        int a = i & l, b = j & l;
        if(a)  l |= j;
        else if(b)  l -= b;
        if(b)  l |= i;
        else if(a)  l -= i;
    }
    return l;
}//将l上的二进制数翻转
int getmin(int l1, int l2, int n1, int n2)
{
    for(int i = 0; i < n2; i++, l1 <<= 1)
        if((l1 & l2) == 0)
            return (n1 + i > n2) ? n1 + i : n2;
    return n1 + n2;
}

roll函数是用来翻转“数组”的

getmin函数是用来得到这两个长条摆放情况的时候的最小容器长度的

input函数就是输入,没得说

你可能感兴趣的:(c语言,算法)