hdu ACM Steps 2.2

来源:互联网 发布:下载神圣计划软件 编辑:程序博客网 时间:2024/04/29 22:44

2.2.1 Fibonacci

通项公式求值,再取对数求高四位,很巧妙的方法

n较大时小数部分的幂趋向0,可以舍弃。

取对数后值的整数部分代表位数,小数部分保存了具体信息(类似科学计数法)

之后用小数部分求出前四位即可

#include<stdio.h>#include<cmath>using namespace std;int fac[21]={0,1,1};const double f=(sqrt(5.0)+1.0)/2.0;int main(){double bit;int n;for (int i=3;i<=20;i++) fac[i]=fac[i-1]+fac[i-2];while (scanf("%d",&n)!=EOF){if (n<=20){printf("%d\n",fac[n]);continue;}bit=-0.5*log(5.0)/log(10.0)+((double)n)*log(f)/log(10.0);bit=bit-floor(bit);bit=pow(10.0,bit);while (bit<1000) bit=bit*10.0;printf("%d\n",(int)bit);}return 0;}


2.2.2 Joseph

先摆Joseph环公式

j=(j+m-1)%(n-i); 可以推出下次淘汰的位置

本题因为k很小,可以预处理答案

枚举m,带入公式模拟检验,这里有一个小优化

因为最后只剩下k+1个人(即一个坏人)时,上次淘汰的肯定在这个坏人的左侧或者右侧

此时m只能为a(k+1)或者a(k+1)+1才能满足条件

#include<stdio.h>using namespace std;int test(int k,int m){int i,j=0,n=k<<1;for (int i=0;i<k;i++){j=(j+m-1)%(n-i);if (j<k) return 0;}return 1;}int main(){int k;int x[13];for (k=1;k<14;k++){int i=k+1;while(1){if (test(k,i)){x[k-1]=i;break;}if (test(k,i+1)){x[k-1]=i+1;break;}i+=(k+1);}}while (scanf("%d",&k),k){printf("%d\n",x[k-1]);}return 0;}


2.2.3 汉诺塔VII

及其恶心的一个递推题,首先明白汉诺塔的应有顺序,之后不断判断当前数是否在可行位置就行

#include<stdio.h>int main(){    int one[4],n[4],h[4][65],a,b,c,i,N,cas,t,flag;    scanf("%d",&cas); while(cas--)    {        a=1;b=2;c=3;        one[a]=one[b]=one[c]=1;        scanf("%d",&N);        scanf("%d",&n[a]);        for(i=one[a];i<=n[a];i++)        scanf("%d",&h[a][i]);        scanf("%d",&n[b]);        for(i=one[b];i<=n[b];i++)        scanf("%d",&h[b][i]);        scanf("%d",&n[c]);        for(i=one[c];i<=n[c];i++)        scanf("%d",&h[c][i]);        flag=1;        while(1)        {            if(n[c]==N||n[a]==N) {flag=1;break;}            if(n[b]>0&&h[b][one[b]]==N) {flag=0;break;}            if(n[a]>0&&h[a][one[a]]==N){    N--;    n[a]--;    one[a]++;    t=b;b=c;c=t;    continue;   }            if(h[c][one[c]]==N&&n[c]>0){    N--;    n[c]--;    one[c]++;    t=b;b=a;a=t;    continue;   }        }        if(flag) printf("true\n");        else printf("false\n");    }    return 0;}


2.2.4 Wolf and Rabbit

#include<stdio.h>using namespace std;int n,m;int gcd(int x, int y){    if (!x || !y) return x>y ? x : y;    for (int t; t=x%y; x=y,y=t);    return y;}int main(){    int p;    scanf("%d",&p);    while (p--)    {        scanf("%d %d",&m,&n);        if (gcd(m,n)==1) printf("NO\n");                   else printf("YES\n");        }    return 0;}


2.2.5 三角形

简单递推

#include<stdio.h>using namespace std;int n;int ans[20000];void init(){    ans[1]=2;    int d=6;    for (int i=2;i<=10000;i++)    {        ans[i]=ans[i-1]+d;        d+=6;    }}int main(){    init();    int t;    scanf("%d",&t);    while (t--)    {        scanf("%d",&n);        printf("%d\n",ans[n]);    }    return 0;}


2.2.6 Digital Roots

看看当初傻傻的自己,哎

#include<iostream>#include<string>using namespace std;int digit(int n){    int x = 0;    while (n>0)    {        x += n%10;        n /= 10;    }    if (x<10) return x;        else return digit(x);}int digit(string st){    int x = 0;    for (int i=0;i<st.length();i++)    x += st[i]-'0';    return x;}int main(){    int n;    string st;    cin>>st;    n = digit(st);    while (n!=0)    {        cout<<digit(n)<<endl;        cin>>st;        n = digit(st);    }    return 0;}


2.2.7 Last non-zero Digit in N!

这题现在也只是理解了小半,方法不是原创

传送门:http://blog.csdn.net/fengyu0556/article/details/5615129

#include<stdio.h>#include<string.h>#define MAXN 10000using namespace std;int lastdigit(char* buf){    const int mod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2};    int len = strlen(buf),a[MAXN],i,c,ret = 1;    if (len==1) return mod[buf[0]-'0'];    for (i = 0;i<len;i++) a[i]=buf[len-i-1]-'0';     for (;len;len-=!a[len-1])    {        ret=ret*mod[a[1]%2*10+a[0]]%5;        for (c=0,i=len-1;i>=0;i--)            c=c*10+a[i],a[i]=c/5,c%=5;    }    return ret+ret%2*5;}int main(){    char n[MAXN];    while (scanf("%s",&n)!=EOF)    printf("%d\n",lastdigit(n));    return 0;}


2.2.8 N!Again

2009呵呵呵呵呵,莫非要壮哉我大酒神?

#include<stdio.h>using namespace std;int cal(int x){    int ret = 1;    for (int i=2;i<=x;i++)    {        ret *= i;        ret %= 2009;    }    return ret;}int main(){    int n;    while (scanf("%d",&n)!=EOF)    {        if (n>=41) printf("0\n");            else printf("%d\n",cal(n));    }    return 0;}