码迷,mamicode.com
首页 > 其他好文 > 详细

做了点数论的题

时间:2019-01-18 20:06:36      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:错排   set   include   code   put   告诉   i++   double   its   

错位排列

这是一道水题,名字就直接告诉了题的内容和做题的方法,那么直接使用公式就可以了

//错排问题
//就是不可以放在自己原来的位置上 
//那么直接根据公式来就可以了
//D=n!*(1-1/1!+1/2!+...) 
#include<bits/stdc++.h>
using namespace std;
long long fact[15];
inline void init(){
    fact[0]=1;
    for(int i=1;i<=12;i++)fact[i]=fact[i-1]*i;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    init();
    long long res;
    int n;
    scanf("%d",&n);
    res=fact[n];
    double tmp=1;
    for(int i=1;i<=n;i++){
        tmp+=(pow(-1,i)/(fact[i]+0.0));
    }
    printf("%.0lf\n",res*tmp);
    return 0;
}

计数器

大概就是统计1~n中每一个数字出现了多少次。有10^9的数量级,所以不可以枚举的。因此要采取把每一位的数字分开来进行计算,即分解每一位,然后这一位前面的数字乘以这一位的权值(它在十的第几位,权值就是十的第几次方),如果说这一位数字大于我们统计的数字,那么还可以再加上一次权值,而如果等于,则应该加上它后面的位数组成的数字+1+1是因为后面的组成的还有全0。比如2533,再统计5时,统计到第三位,因为这这一位等于5,后面的位数组成的数字是33,但是漏了2500,所以要+1(注意0要进行特殊的判定,因为0在最前面是不符合计数的规则的)。
那么代码如下
洛谷的链接

//计数器 
#include<bits/stdc++.h>
using namespace std;
int data[11];
void calc(int num,int tot){
    int cnt=0,k=1,upp,low,now;
    int tmp=tot;
    while(k<=tot){
        upp=tot/(k*10);
        low=tot%k;
        now=tmp%10;
        cnt+=(upp*k);
        if(now>num)cnt+=k;
        if(now==num)cnt+=(low+1);
        if(num==0)cnt-=k;
        k*=10;  
        tmp/=10;
        if(tmp<10&&num==0)break;    
    }
    data[num]=cnt;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    memset(data,0,sizeof(data));
    int n;
    cin>>n;
    for(int i=0;i<=9;i++){
        calc(i,n);
    }
    
    for(int i=0;i<=9;i++)printf("%d\n",data[i]);
    return 0;
}

做了点数论的题

标签:错排   set   include   code   put   告诉   i++   double   its   

原文地址:https://www.cnblogs.com/perisino/p/10289214.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!