📌  相关文章
📜  C ++程序通过避免一组给定字符串来查找最小循环旋转以获得给定数字字符串

📅  最后修改于: 2022-05-13 01:55:20.354000             🧑  作者: Mango

C ++程序通过避免一组给定字符串来查找最小循环旋转以获得给定数字字符串

给定一个长度为N的数字字符串目标和一字符串阻塞的数字字符串,每个长度N任务是通过避免任何存在于任何步骤中的字符串被阻塞。如果不可能,打印 -1。
注意:单次旋转涉及将特定索引处的值增加或减少1 个单位。由于旋转是圆形的,因此可以将 0 转换为 9,或者将 9 转换为 0。
例子:

方法:为了解决这个问题,我们使用以下 BFS 方法:

  • 创建一个长度为N的字符串开头,仅由 0 组成。将其推入队列。创建队列以通过将字符增加或减少一个单位来存储可能的下一个有效组合。
  • 创建一个无序集Avoid ,并在其中添加所有被阻止的字符串。
  • 如果starttarget存在于Avoid中,则无法达到所需的目标。
  • 从队列中弹出start并遍历start的所有字符。将每个字符增加和减少一个单位,保持剩余不变,并检查字符串是否存在于Avoid中。如果不是并且新的组合不等于目标,则将其推入队列并插入到避免中,以防止将来重复相同的组合。
  • 遍历完start的整个长度后,对下一级重复上述步骤,这是从 start 获得的有效字符串,并且当前存在于队列中。
  • 继续重复上述步骤,直到达到目标或没有其他组合并且队列变为空。
  • 在任何时刻,如果形成的字符串等于 target,则返回count的值,该值保留 BFS 遍历的级别数的计数。 count 的值是所需的最小圆周旋转次数。
  • 如果无法获得进一步的状态并且队列为空,则打印“不可能”

下面是上述逻辑的实现:

C++
// C++ Program to count the minimum
// number of circular rotations required
// to obtain a given numeric strings
// avoiding a set of blocked strings
  
#include 
using namespace std;
  
int minCircularRotations(
    string target,
    vector& blocked,
    int N)
{
    string start = "";
    for (int i = 0; i < N; i++) {
        start += '0';
    }
  
    unordered_set avoid;
  
    for (int i = 0; i < blocked.size(); i++)
        avoid.insert(blocked[i]);
  
    // If the starting string needs
    // to be avoided
    if (avoid.find(start) != avoid.end())
        return -1;
  
    // If the final string needs
    // to be avoided
    if (avoid.find(target) != avoid.end())
        return -1;
  
    queue qu;
    qu.push(start);
  
    // Variable to store count of rotations
    int count = 0;
  
    // BFS Approach
    while (!qu.empty()) {
  
        count++;
  
        // Store the current size
        // of the queue
        int size = qu.size();
  
        for (int j = 0; j < size; j++) {
  
            string st = qu.front();
            qu.pop();
  
            // Traverse the string
            for (int i = 0; i < N; i++) {
  
                char ch = st[i];
  
                // Increase the
                // current character
                st[i]++;
  
                // Circular rotation
                if (st[i] > '9')
                    st[i] = '0';
  
                // If target is reached
                if (st == target)
                    return count;
  
                // If the string formed
                // is not one to be avoided
                if (avoid.find(st)
                    == avoid.end())
                    qu.push(st);
  
                // Add it to the list of
                // strings to be avoided
                // to prevent visiting
                // already visited states
                avoid.insert(st);
  
                // Decrease the current
                // value by 1 and repeat
                // the similar checkings
                st[i] = ch - 1;
  
                if (st[i] < '0')
                    st[i] = '9';
                if (st == target)
                    return count;
                if (avoid.find(st)
                    == avoid.end())
                    qu.push(st);
                avoid.insert(st);
  
                // Restore the original
                // character
                st[i] = ch;
            }
        }
    }
  
    return -1;
}
  
// Driver code
int main()
{
    int N = 4;
    string target = "7531";
    vector blocked
        = { "1543",
            "7434",
            "7300",
            "7321",
            "2427" };
  
    cout << minCircularRotations(
                target,
                blocked, N)
         << endl;
  
    return 0;
}


输出:
12

请参阅关于最小圆形旋转的完整文章,通过避免一组给定的字符串来获得给定的数字字符串以获取更多详细信息!