• [JLOI2014]聪明的燕姿(数论)


    [JLOI2014]聪明的燕姿

    题目链接

    题解链接

    题目

    城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。

    可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字 S,那么自己等的人手上的号码牌数字的所有正约数之和必定等于 S。

    所以燕姿总是拿着号码牌在地铁和人海找数字(喂!这样真的靠谱吗)可是她忙着唱《绿光》,想拜托你写一个程序能够快速地找到所有自己等的人。

    分析

    这题其实很简单,其实就是个数论题 + 搜索题。
    启发我们原来数论可以用暴搜解决。
    代码 :

    #include <bits/stdc++.h>
    using namespace std;
    int vis[100005], pri[100005], cnt, tot, ans[100005];
    void shai() {
    	for(int i = 2; i <= 100000; ++i) {
    		if(vis[i] == 0) vis[i] = i, pri[++tot] = i;
    		for(int j = 1; j <= tot; ++j) {
    			if(i * pri[j] > 100000 || pri[j] > vis[i]) break;
    			vis[i * pri[j]] = pri[j];
    		}
    	}
    }
    inline bool pan(int x) {
    	if(x == 1) return 0;
    	for(int i = 2; i * i <= x; ++i) 
    		if(x % i == 0) return 0;
    	return 1;
    }
    void dfs(int now, int x, int s) {
    	if(now == 1) return ans[++cnt] = s, void();
    	if(pan(now - 1) && now > pri[x]) ans[++cnt] = s * (now-1);
    	for(int i = x; pri[i] * pri[i] <= now; ++i) {
    		int t = pri[i], sum = pri[i] + 1;
    		for(; sum <= now; t *= pri[i], sum += t)
    			if(now % sum == 0) dfs(now/sum, i + 1, s * t);
    	}
    }
    int main() {
    	std::ios::sync_with_stdio(false);
    	std::cin.tie(0);
    	shai(); int n;
    	while(cin >> n) {
    		cnt = 0, dfs(n, 1, 1);
    		sort(ans + 1, ans + cnt + 1);
    		cout << cnt << '
    ';
    		for(int i = 1; i <= cnt; ++i) cout << ans[i] << ' ';
    		if(cnt) co	ut << '
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    线程的休眠和中断
    线程的强制运行
    多线程基础
    jar文件につぃて
    Exception和RuntimeException
    异常的抛出
    java之适配器模式
    分支语句
    运算符与表达式
    练习课(一)
  • 原文地址:https://www.cnblogs.com/DZN2004/p/13415129.html
Copyright © 2020-2023  润新知