📜  检查圆形的弦在旋转后是否对称

📅  最后修改于: 2021-10-23 09:04:06             🧑  作者: Mango

给定两个整数NMN表示圆周上的等距点, M表示由这些点形成的弦数。还给出了包含和弦位置的C 对向量。任务是将圆旋转任意度数,例如 X,其中 0 < X < 360,并检查 的弦是否仍然与原始圆对称。

例子:

朴素方法:在范围 [1, N ] 中的每距离K 处旋转,并检查每个点 [a, b] 是否存在旋转点 [a + K , b + K ]。
如果存在任何 k 则打印 YES 否则打印 NO
时间复杂度:O(N*M)

有效的方法:检查 N 的除数就足够了。
让我们假设如果我们将图像旋转K 个单位,那么整个图像将被分成N/K个块。那么如果K不是 N的除数,就会有一个长度小于K的不对称块,并且图像永远不会与原始图形对称。
因此,计算N 的所有除数并检查每个和弦旋转和弦是否存在。

下面是上述方法的实现:

C++
// C++ Program to for the above approach
  
#include 
using namespace std;
  
// Utility function to calculate
// divisors of a number in O(sqrt(N))
vector calculateDivisors(int N)
{
    vector div;
    for (int i = 1; i * i <= N; i++) {
        if (N % i == 0) {
            div.push_back(i);
            if (N / i != i && i != 1) {
                div.push_back(N / i);
            }
        }
    }
    return div;
}
int checkRotationallySymmetric(
    vector > A,
    int N, int M)
{
    // Maintain a set to check quickly
    // the presence of a chord
    set > st;
    for (int i = 0; i < M; i++) {
        --A[i].first, --A[i].second;
        if (A[i].first > A[i].second) {
            swap(A[i].first, A[i].second);
        }
        st.insert(A[i]);
    }
  
    // Calculate the divisors of N.
    vector div = calculateDivisors(N);
  
    // Iterate through the divisors
    for (auto x : div) {
        bool exist = 1;
        for (int i = 0; i < M; i++) {
            int dx = (A[i].first + x) % N;
            int dy = (A[i].second + x) % N;
            if (dx > dy) {
                swap(dx, dy);
            }
            if (st.find({ dx, dy }) != st.end()) {
  
                // There exists a vaild
                // chord after rotation
            }
            else {
  
                // There is no valid chord after rotation
                exist = false;
                break;
            }
        }
  
        // if there exist another chord after
        // rotation for every other chord print
        // YES and exit the function
        if (exist) {
            cout << "YES";
            return 0;
        }
    }
    cout << "NO";
    return 0;
}
  
// Driver Code
int main()
{
    int N = 12, M = 6;
    vector > C
        = { { 1, 3 }, { 3, 7 }, { 5, 7 },
             { 7, 11 }, { 9, 11 }, { 11, 3 } };
    checkRotationallySymmetric(C, N, M);
    return 0;
}


输出
YES

时间复杂度: O(M*sqrt(N)*log M)
空间复杂度: O(M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。