#include<iostream>#include<vector>usingnamespacestd;intmain(){intn;cin>>n;// Special Judge: n == 1, put 1.if(n==1){cout<<"1\n";returnEXIT_SUCCESS;}intdates[200000];vector<int>intervals;cin>>dates[0];// first day is 1, not needed.for(inti=1;i<n;++i){cin>>dates[i];--dates[i];// -1 to show the interval.boolhas_divisor=false;for(autoj:intervals)if(dates[i]%j==0){has_divisor=true;break;}if(has_divisor==false){intervals.push_back(dates[i]);}}cout<<intervals.size()<<'\n';}
首先,在 WA 了一发后发现对 n = 1 的情况要特判一下输出1……
分析题意,可以得到性质1:
这是因为在第二个天数之前不存在其他的小朋友到达,所以这个间隔数必然是对的。把这个间隔数记录下来。
还有性质2:
根据这个性质写出代码:
复杂度是 $O(n^2)$,可以应对这题五次方的数据量。
include
下面是一个O(n)的C++实现,使用hash表空间换时间。
include
include
define maxn 200010
using namespace std;
int dates[maxn] = {0}; //所有记录日期
int hash_tag[maxn] = {0}; //hash_tag[i]标记第i天是否有人会来,初始化均为无人
int solve(int m)
{
int date, ans = 0, remains = m - 1; //remains记录剩下无人来的日期
for(int i = 1; i < m && remains > 0; i++)
{
date = dates[i];
if(hash_tag[date] == 0)//当这一天无人来时,需要安排一个人这天来
{
ans++;
while(date <= dates[m - 1] && remains > 0) //标记所有这个人会来的日期
{
if(hash_tag[date] == 0) //若无人来,则标记有,且剩余无人来的天数减少
{
hash_tag[date] = 1;
remains–;
}
date += (dates[i] - 1); //下次会来的日期
}
}
}
return ans;
}
int main(){
int n;
cin >> n;
}