2017程序设计练习题之数学专题

A题

//res=(x-1)*x/2+y
#include<bits/stdc++.h>

using namespace std;


int main()
{
    __int64 res,x,y;
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%I64d",&x);
        scanf("%I64d",&y);
        res=(x-1)*x/2+y;
        printf("%I64d\n",res);
    }
    return 0;
}

B题

//先计算取余为0,1,2的个数a,b,c、所以结果为C(a,3) + C(b,3) + C(c,3) + a*b*c;
//不过这题取余有点恶心。
#include<bits/stdc++.h>

using namespace std;
#define mod 1000000007
int main(){
    int n;
    while(~scanf("%d",&n)&&n){
        int sum_1,sum_2,sum_3;
        sum_1 = sum_2 = sum_3 = n/3;
        n -= (n/3*3);
        if(n==1)sum_1++;
        if(n==2){sum_1++;sum_2++;}
        if(n==0);
        __int64 a = sum_1;
        __int64 b = sum_2;
        __int64 c = sum_3;
        __int64 z=a*b*c%mod;
        z=(z+(c-2)*c*(c-1)/6%mod)%mod;
        z=(z+(a-2)*a*(a-1)/6%mod)%mod;
        z=(z+(b-2)*b*(b-1)/6%mod)%mod;
        printf("%I64d\n",z);
    }
    return 0;
}

C题

//l + sqrt(l^2 + s ^2)公式自己推一下亲。
#include<bits/stdc++.h>

using namespace std;

int main()
{
    int l,s;
    while(~scanf("%d%d",&l,&s)&s+l){
        printf("%.2f\n",(double)l + sqrt(l*l+s*s));
    }
}

D题

//自己推下吧不太好写,然后暴力n如果不够的话再乘一次。

#include<stdio.h>
#include<math.h>
int Pow(int x,int n)
{
    int res=1;
    for(int i=0; i<n; i++)
        res*=x;
    return res;
}
int main()
{
    int a,b,t;
    scanf("%d",&t);
    while(t--)
    {
        int i=1;
        scanf("%d%d",&a,&b);
        if(b==0&&a!=0||(a==0&&b!=0)||(a!=100&&b==100))
        {
            printf("Impossible\n");
            continue;
        }
        else
        {
            double tmp=100.0-a;
            while(100-tmp<b){
                tmp*=(1.0-a/100.0);
                i++;
            }
            printf("%d\n",i);
        }
    }
}

E题

//先算最小因子分解式,然后如何处理看代码吧,就是个公式。代码中的分解方法可能更有价值...

#include<bits/stdc++.h>

using namespace std;
int a[2][32];//a[0]存质因数,a[1]存个数
int Pow(int x,int n){
    int res = 1;
    for(int i = 0;i < n;i++)res*=x;
    return res;
}

int f(int x)
{
    //printf("%d\n",x);
    int y = 0,i;
    for(i = 0;i <= a[1][x];++i)
        y += Pow(a[0][x],i); //      将每一个因数的各次幂加在一起
    if(x == 0)
        return y;
    else
        return y * f(x - 1);    //然后互相做乘法
}


int main(){
    int n;
    while(~scanf("%d",&n)&&n){
        if(n==1){puts("1");continue;}
        int y = 0;
        int j = 0;
        if(n%2==0){
            int k = 0;
            a[0][j] = 2;
            for(;n%2==0;k++)n/=2;
            a[1][j++] = k;
        }
        for(int i = 3;i * i <= n;i+= 2) //判断其他质因数
            if(n % i == 0)
            {
                int k;
                a[0][j] = i;
                for(k = 0;n % i == 0;++k)
                    n = n / i;
                a[1][j++] = k;
            }
        if(n!=1){
            a[0][j] = n;
            a[1][j++] = 1;
        }
        printf("%d\n",f(j-1));
    }
    return 0;
}

F题

//打表记录到c[i]有多少个prime twin然后[a,b]就是c[b]-c[a-1];
//注意最后有可能要减1应为边界问题
//还要注意下a<b不一定成立
#include <stdio.h>
#include <math.h>
#include<string.h>
#define N 5000001
#define SQRT_N  3000
int a[N]={1,1};
int bb[2][N];
int elem[N];
int cnt;
int main(){
     int i,j;
    for(i=2;i<=SQRT_N;i++){
        if(!a[i]){
            for(j=i*i;j<N;j+=i) a[j] = 1;
        }
    }
    int t,c,b;
    elem[0]=0;elem[1]=0;elem[2]=0;elem[3]=0;
    for(i=4;i<5000010;i++)
    {
        if(a[i]==0&&a[i-2]==0)elem[i]=elem[i-1]+1;
        else elem[i]=elem[i-1];
    }
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&c,&b);
        if(c>b)
        {
            int temp=c;c=b;b=temp;
        }
        int res=elem[b]-elem[c];
        if(!a[c+1]&&!a[c-1])
            res--;
        printf("%d\n",res);
    }
    return 0;
}

G题

//1~n的立方和为n^2*(n+1)^2/4所以用1~b的立方和减去1~(a-1)的立方和就是[a,b]的立方和
#include<bits/stdc++.h>

using namespace std;
#define mod 10003
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        long long a,b,sum,p=10003;
        scanf("%I64d%I64d",&a,&b);
        if(a==1) {
            sum=(((b*(b+1)/2%p)*(b*(b+1)/2))%p)%p;
            printf("%I64d\n",sum);
        } else if(a<b) {
            sum=(((b*(b+1)+a*(a-1))/2%p)*((b*(b+1)-a*(a-1))/2%p))%p;
            printf("%I64d\n",sum);
        } else {
            sum=(((a*(a+1)+b*(b-1))/2%p)*((a*(a+1)-b*(b-1))/2%p))%p;
            printf("%I64d\n",sum);
        }
    }
    return 0;
}

H题

//dfs,如果i是满足条件的继续判断i*10+j(j=1,2,3...9)判断是不是素数如果是就以i*10+j作为i继续搜索。
#include <cstdio>
#include <cstring>
#include<cmath>
#include<algorithm>
int sh[84];
int index2=0;
int num = 8;
int isprime(int n)
{
    if (n == 1) return 0;
    int m = floor(sqrt(n));
    for(int i = 2;i <= m;i++)
    {
        if(n%i == 0) return 0;
    }
    return 1;
}

void  searchn(int n,int index)
{
    int k;
    if(index <= num) {
          //  printf("%d\n",n);
    sh[index2++] = n;}

    for(int i=1;i < 10;i++)
    {
        k = n*10+i;
        if(isprime(k) == 1) {searchn(k,index+1);}
    }
}
int main()
{
    searchn(2,1);
    searchn(3,1);
    searchn(5,1);
    searchn(7,1);
    std::sort(sh,sh+83);
    for(int i=0;i < 83;i++)
    printf("%d %d\n",i+1,sh[i]);

    return 0;
}

I题

//先判断每个元素置换回去需要几次,然后由于所有的都要置换回去,也即是最小公倍数。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
const int maxn = 1010;
int a[maxn],n,t;
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        int res = 1;
        for(int i=1;i<=n;i++){
            int pos=i;
            int tmp=0;
            do{
                pos=a[pos];
                tmp++;
            }while(pos!=i);
            res=res/gcd(res,tmp)*tmp;
        }
        printf("%d\n",res);
    }
}

J题

//应为可以出现的可能数字只有位数*9,为何这么说呢。他本身的数+他的数码和=现在数。但是数码和最多也就是有多少位9所以我就暴力了一下,可能有其他的数学方法。

include<bits/stdc++.h>

using namespace std;

int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int t = n;
int a = 0;
while(t){a++;t/=10;}
bool flag = false;
for(int i = n-a*9;i <= n;i++){
int j = i;
int sum = 0;
while(j){sum+=j%10;j/=10;}
if(i+sum==n){
flag = true;
break;
}
}
flag?puts("No"):puts("Yes");
}
return 0;
}

K题

//我用的最暴力的方法,就是看有多少个1不过你每次都要立即取余也就是余数*10+1继续取余,不断下去指导余数=0,不过如果他是2或5的倍数就可以直接g了应为你一辈子也不会取(娶)到0.
#include<bits/stdc++.h>

using namespace std;

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        if(n%2==0||n%5==0){puts("0");continue;}
        int sum = 1;
        int cnt = 1;
        for(int i = 0;sum%n!=0;i++){
            sum = sum*10+1;
            sum %= n;
            cnt++;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

posted @ 2017-06-09 23:00  adfae  阅读(765)  评论(0编辑  收藏  举报