📌  相关文章
📜  三星半导体研究所(SSIR 软件)实习生/FTE |组 1

📅  最后修改于: 2021-11-10 06:57:54             🧑  作者: Mango

有N个钓鱼点和3个大门。在每个门口都有一些渔民在等待到达最近的无人渔场。 (渔民总数<=N)
连续点之间的距离 = 门和最近点之间的距离 = 1 m
一次只能打开一个门,并且该门的所有渔民必须在下一门打开之前占据位置。
距离计算为到最近点的门 + 最近点到最近的空位。
求所有渔民需要步行的最小距离的总和。
要采取的输入:
钓鱼点数
大门的位置
每个门的渔民人数

按照这个例子:

测试用例

钓鱼点总数= 10
5 位渔夫在位于位置 4 的 1 号门,
位于位置 6 的 2 号门的 2 名渔民,
3 号门的 2 名渔民位于位置 10,
如果门按顺序打开 G1->G2->G3

安排将是:

情况1

距离计算为到最近点的门 + 最近点到最近的空位。
G1闸门打开后,渔民被放置在标有1的位置。
距离 = 11m
G2门打开后,渔民被放置在标有2的位置。
距离 = 5m
G3闸门打开后,渔民被放置在标有3的位置。
距离 = 3m
按此顺序的总距离:11 + 5 + 3 = 19

如果门按顺序打开 G2->G1->G3
案例 1 – 2 号门的最后一个渔夫被放置在位置 7
最后的安排是:

案例2B

G2门打开后,渔民被放置在标有2的位置。
距离 = 3m
G1闸门打开后,渔民被放置在标有1的位置。
距离 = 12m
G3闸门打开后,渔民被放置在标有3的位置。
距离 = 3m
按此顺序的总距离:3+12+3 = 18

案例 2 – 2 号门的最后一个渔夫被放置在位置 5
最后的安排是:

案件

G2门打开后,渔民被放置在标有2的位置。
距离 = 3m
G1闸门打开后,渔民被放置在标有1的位置。
距离 = 14m
G3闸门打开后,渔民被放置在标有3的位置。
距离 = 3m
此顺序的总距离:3+14+3 = 20
其他情况是多余的
所以最小距离是 18
解决方案:

生成所有组合并在所有门组合中分配渔民以计算最小步行距离。
生成组合可以以递归和迭代方式完成。现在为了消除不必要的排列,我们可以得出结论,对于最短的步行距离,来自特定门的渔民必须呆在一起,即他们应该占据连续的钓鱼点。因此,我们可以将问题想象为 3 个块(渔夫组)在整个钓鱼范围内滑动。其中的最小值是答案。

C++
#define _CRT_SECURE_NO_WARNINGS
#include
using namespace std;
#define MAX 3
 
int fishspot[100]; // fishing spots
int gate[MAX]; // position of gates
int fishermen[MAX]; // no of fishermen at each gate
int N; // total no of fishing spots
int visited[MAX]; // occupied fishing spots
int Answer; // result
 
// To unmark spots occupied by fishermen of gate# index
class GFG
{
public :
void reset_fishspot(int index)
{
    int i;
    for (i = 1; i <= N; i++)
        if (fishspot[i] == index + 1)
            fishspot[i] = 0;
}
 
// Calculate minimum distance while
// allotting spots to fishermen of gate# index.
// Returns number of positions possible
// with minimum distance.
// pos1, pos2 is used to return positions
int calculate_distance(int index, int*pos1,
                    int *pos2, int *score)
{
    int i, sum = 0, left_min = 999999,
                    right_min = 999999,
                    left, right, npos = 0;
    *pos1 = *pos2 = *score = 0;
 
    left = right = gate[index];
 
    // Allot spots to all fishermen except
    // last based on minimum distance
    for (i = 1; i < fishermen[index]; i++)
    {
        if (fishspot[gate[index]] == 0)
        {
            sum++;
            fishspot[gate[index]] = index + 1;
        }
        else
        {
            left_min = right_min = 999999;
 
            while ((left > 0) && (fishspot[left] > 0))
                left--;
 
            while ((right <= N) &&
                (fishspot[right] > 0))
                right++;
 
            if ((left > 0) && (fishspot[left] == 0))
                left_min = gate[index] - left + 1;
 
            if ((right <= N) && (fishspot[right] == 0))
                right_min = right - gate[index] + 1;
 
            if (right_min == left_min)
            {
                // Place 2 fishermen, if available
                if ((fishermen[index] - i - 1) > 1)
                {
                    fishspot[left] = fishspot[right] = index + 1;
                    sum += (2 * left_min);
                    i++;
 
                    // If all fishermen are alloted spots
                    if (i == fishermen[index])
                    {
                        npos = 1;
                        *score = sum;
                        return npos;
                    }
                }
                else
                {
                    sum += left_min;
                    fishspot[left] = index + 1;
                }
            }
            else if (left_min < right_min)
            {
                sum += left_min;
                fishspot[left] = index + 1;
            }
            else if (right_min < left_min)
            {
                sum += right_min;
                fishspot[right] = index + 1;
            }
        }
    }
 
    left_min = right_min = 99999;
 
    // Allot spot to last fishermen
    while ((left > 0) && (fishspot[left] > 0))
        left--;
 
    if ((left > 0) && (fishspot[left] == 0))
        left_min = gate[index] - left + 1;
 
    while ((right <= N) && (fishspot[right] > 0))
        right++;
 
    if ((right <= N) && (fishspot[right] == 0))
        right_min = right - gate[index] + 1;
 
    if ((sum + left_min) == (sum + right_min))
    {
        npos = 2;
        *pos1 = left;
        *pos2 = right;
        *score = sum + left_min;
    }
    else if ((sum + left_min) >
            (sum + right_min))
    {
        npos = 1;
        *score = sum + right_min;
        fishspot[right] = index + 1;
    }
    else if ((sum + left_min) <
            (sum + right_min))
    {
        npos = 1;
        *score = sum + left_min;
        fishspot[left] = index + 1;
    }
    return npos;
}
 
// Solve is used to select next gate
// and generate all combinations.
void solve(int index, int sum, int count)
{
    int npos, pos1, pos2, score, i;
 
    visited[index] = 1;
 
    if (sum > Answer)
        return;
 
    npos = calculate_distance(index, &pos1,
                            &pos2, &score);
    sum += score;
 
    if (count == MAX)
    {
        if (Answer > sum)
            Answer = sum;
 
        return;
    }
 
    if (npos == 1)
    {
        for (i = 0; i < MAX; i++)
        {
            if (visited[i] == 0)
            {
                solve(i, sum, count + 1);
                visited[i] = 0;
                reset_fishspot(i);
            }
        }
    }
     
    else if (npos == 2)
    {
        fishspot[pos1] = index + 1;
        for (i = 0; i < MAX; i++)
        {
            if (visited[i] == 0)
            {
                solve(i, sum, count + 1);
                visited[i] = 0;
                reset_fishspot(i);
            }
        }
 
        fishspot[pos1] = 0;
        fishspot[pos2] = index + 1;
        for (i = 0; i < MAX; i++)
        {
            if (visited[i] == 0)
            {
                solve(i, sum, count + 1);
                visited[i] = 0;
                reset_fishspot(i);
            }
        }
        fishspot[pos2] = 0;
    }
}
};
 
// Driver Code
int main()
{
    GFG g;
 
    int i;
    /*scanf("%d", &N); // for input
         
    for (i = 0; i < MAX; i++)
    {
        scanf("%d %d", &gate[i], &fishermen[i]);
        visited[i] = 0;
    }*/
     
    N = 10; // total no of fishing spots
     
    // position of gates(1-based indexing)
    gate[0] = 4;
    gate[1] = 6;
    gate[2] = 10;
     
    //no of fishermen at each gate
    fishermen[0] = 5; //gate1
    fishermen[1] = 2; //gate 2
    fishermen[2] = 2; //gate 3
 
    for (i = 1; i <= N; i++)
        fishspot[i] = 0;
 
    Answer = 999999;
 
    for (i = 0; i < MAX; i++)
    {
        g.solve(i, 0, 1);
        visited[i] = 0;
        g.reset_fishspot(i);
    }
 
    cout << Answer << endl;
 
    return 0;
}
 
// This code is contributed by SoM15242


C
#define _CRT_SECURE_NO_WARNINGS
#include
 
#define MAX 3
 
int fishspot[100]; // fishing spots
int gate[MAX];  // position of gates
int fishermen[MAX]; // no of fishermen at each gate
int N; // total no of fishing spots
int visited[MAX]; // occupied fishing spots
int Answer;  // result
 
//To unmark spots occupied by fishermen of gate# index
void reset_fishspot(int index)
{
    int i;
    for (i = 1; i <= N; i++)
        if (fishspot[i] == index + 1)
            fishspot[i] = 0;
}
 
// Calculate minimum distance while allotting spots to
// fishermen of gate# index.
// Returns number of positions possible with minimum distance.
// pos1, pos2 is used to return positions
int calculate_distance(int index, int*pos1, int *pos2, int *score)
{
    int i, sum = 0, left_min = 999999, right_min = 999999,
                                    left, right, npos = 0;
    *pos1 = *pos2 = *score = 0;
 
    left = right = gate[index];
 
    // Allot spots to all fishermen except last based on
    // minimum distance
    for (i = 1; i < fishermen[index]; i++)
    {
        if (fishspot[gate[index]] == 0)
        {
            sum++;
            fishspot[gate[index]] = index + 1;
        }
        else
        {
            left_min = right_min = 999999;
 
            while ((left > 0) && (fishspot[left] > 0))
                left--;
 
            while ((right <= N) && (fishspot[right] > 0))
                right++;
 
            if ((left > 0) && (fishspot[left] == 0))
                left_min = gate[index] - left + 1;
 
            if ((right <= N) && (fishspot[right] == 0))
                right_min = right - gate[index] + 1;
 
            if (right_min == left_min)
            {
                // Place 2 fishermen, if available
                if ((fishermen[index] - i - 1) > 1)
                {
                    fishspot[left] = fishspot[right] = index + 1;
                    sum += (2 * left_min);
                    i++;
 
                    // If all fishermen are alloted spots
                    if (i == fishermen[index])
                    {
                        npos = 1;
                        *score = sum;
                        return npos;
                    }
                }
                else
                {
                    sum += left_min;
                    fishspot[left] = index + 1;
                }
            }
            else if (left_min < right_min)
            {
                sum += left_min;
                fishspot[left] = index + 1;
            }
            else if (right_min < left_min)
            {
                sum += right_min;
                fishspot[right] = index + 1;
            }
        }
    }
 
    left_min = right_min = 99999;
 
    // Allot spot to last fishermen
    while ((left > 0) && (fishspot[left] > 0))
        left--;
 
    if ((left > 0) && (fishspot[left] == 0))
        left_min = gate[index] - left + 1;
 
    while ((right <= N) && (fishspot[right] > 0))
        right++;
 
    if ((right <= N) && (fishspot[right] == 0))
        right_min = right - gate[index] + 1;
 
    if ((sum + left_min) == (sum + right_min))
    {
        npos = 2;
        *pos1 = left;
        *pos2 = right;
        *score = sum + left_min;
    }
    else if ((sum + left_min) > (sum + right_min))
    {
        npos = 1;
        *score = sum + right_min;
        fishspot[right] = index + 1;
    }
    else if ((sum + left_min) < (sum + right_min))
    {
        npos = 1;
        *score = sum + left_min;
        fishspot[left] = index + 1;
    }
 
    return npos;
}
 
// Solve is used to select next gate and generate all combinations.
void solve(int index, int sum, int count)
{
    int npos, pos1, pos2, score, i;
 
    visited[index] = 1;
 
    if (sum > Answer)
        return;
 
    npos = calculate_distance(index, &pos1, &pos2, &score);
    sum += score;
 
    if (count == MAX)
    {
        if (Answer > sum)
            Answer = sum;
 
        return;
    }
 
    if (npos == 1)
    {
        for (i = 0; i < MAX; i++)
        {
            if (visited[i] == 0)
            {
                solve(i, sum, count + 1);
                visited[i] = 0;
                reset_fishspot(i);
            }
        }
    }
    else if (npos == 2)
    {
        fishspot[pos1] = index + 1;
        for (i = 0; i < MAX; i++)
        {
            if (visited[i] == 0)
            {
                solve(i, sum, count + 1);
                visited[i] = 0;
                reset_fishspot(i);
            }
        }
 
        fishspot[pos1] = 0;
        fishspot[pos2] = index + 1;
        for (i = 0; i < MAX; i++)
        {
            if (visited[i] == 0)
            {
                solve(i, sum, count + 1);
                visited[i] = 0;
                reset_fishspot(i);
            }
        }
        fishspot[pos2] = 0;
    }
}
 
int main()// driver function
{
 
          int i;
                /*scanf("%d", &N); // for input
               
        for (i = 0; i < MAX; i++)
        {
            scanf("%d %d", &gate[i], &fishermen[i]);
            visited[i] = 0;
        }*/
         
        N=10; // total no of fishing spots
         
        //position of gates(1-based indexing)
        gate[0]=4;
        gate[1]=6;
        gate[2]=10;
         
        //no of fishermen at each gate
        fishermen[0]=5; //gate1
        fishermen[1]=2; //gate 2
        fishermen[2]=2; //gate 3
         
         
 
        for (i = 1; i <= N; i++)
            fishspot[i] = 0;
 
        Answer = 999999;
 
        for (i = 0; i < MAX; i++)
        {
            solve(i, 0, 1);
            visited[i] = 0;
            reset_fishspot(i);
        }
 
        printf("%d\n", Answer);
     
    return 0;
}


输出:

18