[JZOJ5773]【NOIP2008模拟】简单数学题

Description
      话说, 小X是个数学大佬,他喜欢做数学题。有一天,小X想考一考小Y。他问了小Y一道数学题。题目如下:
      对于一个正整数N,存在一个正整数T(0<T<N),使得

的值是正整数。
      小X给出N,让小Y给出所有可能的T。如果小Y不回答这个神奇的大佬的简单数学题,他学神的形象就会支离破碎。所以小Y求你帮他回答小X的问题。
 
Input
      一个整数N。
Output
      第一个数M,表示对于正整数N,存在M个不同的正整数T,使得

是整数。
后面是M个数,每一个数代表可能的正整数T(按从小到大的顺序排列)。
 
Sample Input
Sample Input1:
1

Sample Input2:
3

Sample Input3
180
Sample Output
Sample Output
0

Sample Output
1 2

Sample Output
5 120 144 160 168 176

 
 
Data Constraint
      对于5%的数据,N=1.
      对于20%的数据,N<=5.
      对于40%的数据,N<=1000000
      对于另外20%的数据,答案只有1个,且N为质数,保证对于前60%的数据,当N为质数的时候,答案都一定只有一个,对于这20%的数据,满足2<N。
      对于80%的数据,N<=10^9.
      对于100%的数据,N<=10^14.

 


 

 

233考场打的大暴力拿了65分。

既没有判断素数又没有打表,竟然暴力拿这么多分真是不敢相信。

放上考场yy代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
#define  int long long
inline int read() {
    int res=0;char c=getchar();bool f=0;
    while(!isdigit(c)) {if(c=='-')f=1;c=getchar();}
    while(isdigit(c))res=(res<<3)+(res<<1)+(c^48),c=getchar();
    return f?-res:res;
}

int tmp[10000005], cnt;

signed main(){
    freopen("math.in", "r", stdin);
    freopen("math.out", "w", stdout);

    int n = read();
    if (n == 1) return puts("0"), 0;
    int ans = 0;
    
    if (n <= 6e7)
    {
        for (register int i = 1 ; i < n ; i ++) 
            if ((n - i / 2) % (n - i) == 0 and (i % 2) == 0) tmp[++ans] = i;
        printf("%lld ", ans);
        for (register int j = 1 ; j <= ans ; j ++) printf("%lld ", tmp[j]);
        return 0;
    }
    
    int tt = n - 3 * sqrt(n);
    tt = max(tt, (int)0);
    if (tt % 2 == 1) tt--;
    for (register int i = tt ; i < n ; i += 2) 
        if ((n - i / 2) % (n - i) == 0) tmp[++ans] = i;
    printf("%lld ", ans);
    for (register int i = 1 ; i <= ans ; i ++) printf("%lld ", tmp[i]);
    return 0;    
}
暴力

其实它给的暴力分是40分(逃。。

然后聊聊正解233.

设...算了不写了233.

放个网址就跑题解

然后有不少细节要注意,比如枚举i的时候一定要判断是不是奇数,和最后答案是不是奇数。

 


 

 

 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define int long long
inline int read() {
    int res=0;char c=getchar();bool f=0;
    while(!isdigit(c)) {if(c=='-')f=1;c=getchar();}
    while(isdigit(c))res=(res<<3)+(res<<1)+(c^48),c=getchar();
    return f?-res:res;
}

int tmp[2*10000005], cnt;

signed main()
{
    int n = read();
    n <<= 1;
    int ans = 0;
    for (register int i = 2 ; i <= sqrt(n) ; i ++)
    {
        if (n % i == 0)
        {
            if (i % 2 == 1) tmp[++ans] = n / i * max(((i - 1) / 2), (int)1);
            int t = n / i;
            if (i != t and t % 2 == 1)
                tmp[++ans] = n / t * max(((t - 1) / 2), (int)1);
        }
    }
    int tt = ans;
    sort(tmp + 1, tmp + 1 + ans);
    for (register int i = 1 ; i <= tt ; i ++) if (tmp[i] % 2 == 1) tmp[i] = 0, ans--;
    printf("%lld ", ans);
    for (register int i = 1 ; i <= tt ; i ++) if(tmp[i]) printf("%lld ", tmp[i]);
    return 0;
}

 

转载于:https://www.cnblogs.com/BriMon/p/9443817.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值