問題 H: 嚎叫響徹在貪婪的廠房
時間限制: 1 Sec 內存限制: 128 MB
題目描述
RX:把機器人Hobo,帶往改造工廠。
來到了改造工廠,Hobo感到陣陣迷茫,不知道自己將會何去何從。
“當我從這里離開的時候,我還會是Eddie的朋友嗎?”
RX:珍娜女王,可以開始了。
鐵斯塔:珍娜女王,等到把Hobo改造完了,你父親的遺願就能實現了。
機器人的哀嚎傳遍了整座工廠,於是,Hobo決定帶着他們一起逃離這里。工廠的傳送帶上依次排列着N個機器人,其中,第i個機器人的質量為Ai。Hobo經過仔細觀察,發現:
1.來自同一個家族的機器人,在這N個機器人中一定是連續的一段。
2.如果從第i個機器人到第j個機器人都來自同一個家族,那么Ai到Aj從小到大排序后一定是公差大於1的等差數列的子序列。
Hobo發現,不同家族的個數越少,機器人就會越團結,成功逃離工廠的概率就會越高。Hobo想知道,這N個機器人最少來自幾個不同的家族呢?
輸入
第一行一個正整數N。
接下來一行N個正整數,第i個正整數為Ai。
輸出
一行一個正整數,表示答案。
樣例輸入 Copy
【樣例1】
7
1 5 11 2 6 4 7
【樣例2】
8
4 2 6 8 5 3 1 7
樣例輸出 Copy
【樣例1】
3
【樣例2】
2
提示
樣例1解釋
1 5 11 是等差數列{1,3,5,7,9,11}的子序列,
2 4 6 是等差數列{2,4,6,8}的子序列,
7 是等差數列{7,9,11}的子序列。
樣例2解釋
2 4 6 8 是等差數列{2,4,6,8}的子序列,
1 3 5 7 是等差數列{1,3,5,7}的子序列。
【數據范圍】
20% 的數據滿足, N ≤ 10 。 N ≤ 10 。 N≤10。
40% 的數據滿足, N ≤ 100 。 N ≤ 100 。 N≤100。
60% 的數據滿足, N ≤ 1000 , 1 ≤ A i ≤ 1 0 6 。 N ≤ 1000 , 1 ≤ Ai ≤ 10^6 。 N≤1000,1≤Ai≤106。
另有 20% 的數據滿足, Ai 互不相同。
100% 的數據滿足, N ≤ 100000 , 1 ≤ A i ≤ 1 0 9 。 N ≤ 100000 , 1 ≤ Ai ≤ 10^9 。 N≤100000,1≤Ai≤109。
題意:
給出你 n n n個機器人的質量 a i a_i ai
他們有兩點要求:
- 同廠的機器人連續出現
- 同廠的機器人排序完,符合等差數列的性質,且公差大於1
問你這個 n n n個機器人最少的出自幾個廠家(家族)?
思路
先說下滿足等差數列的性質 ( 2 , 4 , 8 , 12 ) (2 ,4 ,8, 12) (2,4,8,12)這樣也是滿足的他們是公差是 2 2 2的等差數列的一段。其實看樣例解釋就能看出來。
公 差 大 於 1 公差大於1 公差大於1換種理解方式假設 a , b , c a,b,c a,b,c 公差大於1我們就可以這樣理解
x = a b s ( a − b ) x=abs(a-b) x=abs(a−b)
y = a b s ( c − b ) y=abs(c-b) y=abs(c−b)
因為公差大於 1 1 1所以 g c d ( x , y ) > 1 gcd(x,y)>1 gcd(x,y)>1。如果還是理解不了的話往下看。理解也要往下看。
換種解釋:假設公差為 d 且 ( d > 1 ) d且(d>1) d且(d>1)那么設 a a a是首項,然后 x x x是差那么 ( d ∣ x ) (d|x) (d∣x) , x x x整除 d d d. 同理 ( d ∣ y ) (d|y) (d∣y), y y y整除 d d d,所以差的 g c d gcd gcd大於1就滿足條件。
上面這個推推就出來了
看細節:如果兩個相同的數連着那么他就一定不行,差就是零,直接退出,新增廠家。
(這些其實最后用的mp就解決了,之所以列出來只是,方便理解,跟fw思路走)然后差為 1 1 1也是不行的, g c d gcd gcd會成為1也該新增廠家。
如果滿足 g c d > 1 gcd>1 gcd>1那么直接把這個機器人加到這個廠里,那么就把新的 g c d gcd gcd當成比較對象。
這樣你會過50.i am sorry
其實少考慮情況了就是 當 g c d ( ) gcd() gcd()滿足是他一樣的不能出自一個廠家不論他是否連着。所以我們用mp標記一下就可以了。
注意mp標記
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e5+7;
#define pii pair<ll,ll>
const int mod=1e9+7;
ll qpow(ll a,ll b) {
ll sum=1;
while(b) {
if(b&1)sum=sum*a%mod;
b>>=1;
a=a*a%mod;
}
return sum;
}
ll a[maxn],d[maxn];
ll gcd(ll a,ll b) {
while(b) {
ll tmp=a%b;
a=b;
b=tmp;
}
return a;
}
map<ll ,ll >mp;
int main() {
ll n,m;
cin>>n;
for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
ll sum=1,p;
p=abs(a[2]-a[1]);
///mp[a[2]]=1;
mp[a[1]]=1;
for(int i=2; i<=n; i++) {
if(mp[a[i]]==1){
mp.clear();
mp[a[i]]=1;
sum++;
p=abs(a[i+1]-a[i]);
continue;
}
if(p==0||p==1){
mp.clear();
mp[a[i]]=1;
p=abs(a[i+1]-a[i]);
sum++;
continue;
}
ll q=abs(a[i]-a[i-1]);
if(q==0||q == 1) {
mp.clear();
mp[a[i]]=1;
p=abs(a[i+1]-a[i]);
sum++;
continue;
}
if(gcd(q,p)==1) {
mp.clear();
mp[a[i]]=1;
p=abs(a[i+1]-a[i]);
sum++;
} else {
p=gcd(q,p);
mp[a[i]]=1;
}
}
cout<<sum<<endl;
return 0;
}
