zoukankan      html  css  js  c++  java
  • CF1147B Chladni Figure

    洛谷传送门 CF传送门

    题意

    给你一个 (n) 个点的图,其中有 (m) 条线段。求该图形是否为旋转对称图形。

    Solution

    我们设旋转 (x) 个点可以和原图形重合,那么 (kcdot x) 个点也可以

    反过来,已知旋转一圈就是原图形,此时旋转了 (n) 个点,我们只要找到一个 (n) 的因子满足旋转后和原图形重合即可。

    那么我们枚举 (n) 的因子和每一位旋转后的情况就好了

    判断时设此时枚举到 (d(d|n)) 和第 (i) 位,只要判断 (i,i+d) 所含的线段数量是否相等和每一条线段是否都对应。

    小剪枝:枚举每一位的过程中如果出现不相等的情况可以立即跳出,枚举 (n) 的因子的过程中如果出现满足答案的情况就立即跳出。

    注意:输入线段的两个端点 (u,v) 时,是有两条线段的,一条是 (v-u) ,一条是 (u-v+n) ,记得都储存

    Code

    #include<bits/stdc++.h>
    
    using namespace std;
    const int N=1e5+10;
    vector<int> d,p[N];
    int n,m,flag=1;
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n/2;i++)
            if(n%i==0) d.push_back(i);
        for(int i=1,u,v;i<=m;i++){
            scanf("%d%d",&u,&v);
            if(u>v) swap(u,v);
            p[u].push_back(v-u);
            p[v].push_back((n+u-v-1)%n+1);
        }
        for(int i=1;i<=n;i++)
            sort(p[i].begin(),p[i].end());
        for(int i=0;i<d.size();i++){
            flag=1;
            int now=d[i];
            for(int j=1;j<=n;j++){
                if(p[j].size()!=p[(j+now-1)%n+1].size()){
                    flag=0;
                    break;
                }
                for(int k=0;k<p[j].size();k++){
                    if(p[j][k]!=p[(j+now-1)%n+1][k]){
                        flag=0;
                        break;
                    }
                }
                if(flag==0) break;
            }
            if(flag==1) break;
        }
        if(flag==0) puts("No");
        else puts("Yes");
        return 0;
    }
    
  • 相关阅读:
    Hash表的查找-C语言
    二叉排序树-C语言
    线性表的查找算法-C语言
    拓扑排序和关键路径
    图结构的创建与遍历-C语言
    MySQL数据库基本脚本命令
    哈夫曼树编码-C语言
    协程简述
    Python多线程编程-Threading库
    Python多进程编程-multiprocessing库
  • 原文地址:https://www.cnblogs.com/jasony/p/13872576.html
Copyright © 2011-2022 走看看