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; }
相关文章推荐
- 【51Nod 1616】【算法马拉松 19B】最小集合
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合(数论)(枚举)
- [暴力 乱搞] 51Nod 1616 算法马拉松19 B 最小集合
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616:最小集合
- 51nod-1616 最小集合
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合(数论)(枚举)
- 【51NOD 1616】【51NOD 算法马拉松19】最小集合
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合
- 51nod 1616 最小集合(数论)(枚举)
- 51nod 1616 最小集合
- 51nod 1616 最小集合(数论)(枚举)