Description
一个圆上有等距的 n 个顶点,有一些顶点不能选,问是否选取若干点组成一个正多边形,
Input
第一行一整数
Output
如果可以选取一些点组成正多边形则输出 YES ,否则输出 NO
Sample Input
6
1 0 1 1 1 0
Sample Output
YES
Solution
假设可以构成一个正
d
多边形 ,首先需要
枚举 n 的因子 d ,以 dp[i] 表示以 i 结尾最多可以有几个连续的距离均为 d 的点,进而有转移方程
dp[i]=0,a[i]=0
dp[i]=1,a[i]=1,i≤d
dp[i]=dp[i−d]+1,a[i]=1,i>d
如果存在某个 dp[i]≥nd 则说明有解
时间复杂度 O(nn√)
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=100005;
int n,a[maxn],dp[maxn];
bool check(int d)
{
if(n/d<3)return 0;
for(int i=1;i<=n;i++)
{
if(a[i]==0)dp[i]=0;
else
{
if(i>d)dp[i]=dp[i-d]+1;
else dp[i]=1;
}
if(dp[i]==n/d)return 1;
}
return 0;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int flag=0;
for(int i=1;i<=n;i++)
if(n%i==0)
if(check(i)||check(n/i))
{
flag=1;
break;
}
printf("%s\n",flag?"YES":"NO");
}
return 0;
}