您的位置:首页 > 其它

多校联合 第二场 A

2013-04-03 09:58 190 查看

1477:小Y做家教

TimeLimit:2SecMemoryLimit:
64MB

Submit:243Solved:49

Submit
Status
WebBoard

Description

小Y经过千辛万苦,跋山涉水,终于挤过了高考的独木桥,进了大学,作为他家所在的那条街为数不多的大学生,也算这条街上的名人了~这不寒假刚回家,邻居家阿姨就过来找他让他去辅导一下她家在上高三的MM,小Y顿时感到这是他实现人生价值的最好的方式了

(o(╯□╰)o).可是刚来MM就给他一个难题:

有这样的一个集合,集合由N个不同的正整数组成,一旦集合中的两个数x,y满足y=P*x,那么就认为x,y这两个数是互斥的,现在想知道给定的一个集合中两两之间不互斥的子集最多能有多少个元素。小Y在学校经过一个学期的各种游戏训练,对这种问题已经无能为力了,只好去百度提问,这不,正巧你看到了,你能帮帮他么(这年头DS找妹子不容易)~

Input

输入有多组数据,每组第一行给定两个数N和P(1<=N<=10^5,1<=P<=10^9)。接下来一行包含N个不同正整数ai(1<=ai<=10^9)。

Output

输出一行表示满足要求的子集的最大元素个数。

SampleInput

42
1234


SampleOutput

3





这道题因为数据量比较大,直接二重循环来排除元素,可能会超时。。。


所以。。。需要优化啊~


优化的方法是:先对数进行排序,然后从最小的元素开始找与之成p倍的数。找到了如果小的那个数没有被标记,那么就标记大的数,如果小的被标记了,那么就不再标记了;

(这是因为要考虑124的情况);标记之后,再接着之前小的那个数向下找与之可以成p倍的数(向下是指接着上次成匹配的地方)。。。如果一直到找完,都找不到数与之匹配,那么就完成了,因为数列进行了排序,所以如果一个数找不到与之匹配的数(都小于),那么它后面的数也就都会找不到。


这样,时间复杂度就减少了~


代码:


[code]#include<iostream>
#include<algorithm>
#include<string.h>
usingnamespacestd;
inta[100005];
intflag[100005];
intmain(){
intn,p;
while(cin>>n>>p){
for(inti=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
memset(flag,0,sizeof(flag));
inttemp=1;
for(intj=0;j<n;j++){
if(flag[j]==0){
intk;
for(k=temp;k<n;k++){
if(a[j]*p==a[k]){
if(flag[j]==0){
//cout<<a[j]<<""<<a[k]<<endl;
flag[k]=1;
}
temp=k+1;
break;
}
elseif(a[j]*p<a[k]){
break;
//temp=k+1;
}
}
if(k>=n){
break;
}
}
}
intsum=0;
for(intg=0;g<n;g++){
//cout<<flag[g]<<endl;
if(flag[g]==1){
sum++;
}
}
cout<<n-sum<<endl;
}
return0;
}

[/code]

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: