您的位置:首页 > 其它

51Nod-1616-最小集合

2017-07-03 14:47 246 查看
ACM模版

描述



题解

首先,用 vis[] 表示每一个数字的存在状态,然后枚举每一个不存在的数,一直枚举到 mx,判断其所有倍数的 GCD 结果是否等于他,如果等于,那么一定是存在这个数的,否则就是不存在,然后累计结果就行了。

看到官方题解比我的写法要快很多,判断次数少很多,十分有趣,贴出来大家看看吧!



代码

#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN = 1e6 + 10;

int n;
int cnt = 0, mx = 0;
int vis[MAXN];

template <class T>
inline void scan_d(T &ret)
{
char c;
ret = 0;
while ((c = getchar()) < '0' || c > '9');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0'), c = getchar();
}
}

int kgcd(int a, int b)
{
if (a == 0)
{
return b;
}
if (b == 0)
{
return a;
}
if (!(a & 1) && !(b & 1))
{
return kgcd(a >> 1, b >> 1) << 1;
}
else if (!(b & 1))
{
return kgcd(a, b >> 1);
}
else if (!(a & 1))
{
return kgcd(a >> 1, b);
}
else
{
return kgcd(abs(a - b), min(a, b));
}
}

int main(int argc, const char * argv[])
{
scan_d(n);

int x;
for (int i = 0; i < n; i++)
{
scan_d(x);
if (!vis[x])
{
cnt++;
vis[x] = 1;
mx = max(mx, x);
}
}

int tmp;
for (int i = 1; i <= mx; i++)
{
if (vis[i])
{
continue;
}
tmp = 0;
for (int j = i; j <= mx; j += i)
{
if (vis[j])
{
tmp = kgcd(tmp, j);
}
}
if (tmp == i)
{
cnt++;
}
}

cout << cnt << '\n';

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