文章标题

P1095约瑟夫问题10E100版
今天正在疯狂搬运时遇到的一道题,
以为是一道水题,仔细一看,好家伙,高精度(100位)
不能模拟去做,只能尝试用数学方法。
。。。推演后发现,一个N的圈子,可以将其划分为N/2,和N-N/2的两个小圆圈,而N的约瑟夫数为
两个小圈约瑟夫数之和再-1。
然后,就是大精度的除法和减法。
配合后,binary函数中10^100/2^M,M远远大于300次,直接爆栈。
无可奈何,只过了3个点。
但是把这次程序放上来,纪念一下吧。
<一>、对约瑟夫问题求解

#include<stdio.h>
#include<stdbool.h>
#define MAX 100005
int main()
{
    int N;
    int a[MAX];
    bool visit[MAX];
    int i;
    int sum=0;
    int flag=1;
    scanf("%d",&N);
    for(i=1;i<=N;i++)
    {
        a[i]=i;
        visit[i]=false;
    }
    i=1;
    while(sum!=N-1)
    {
        if(i>N)
        i=1;
        if(visit[i])
        {
            i++;
            continue;
        }
        else
        {
            if(flag)
            {
                flag^=1;
                i++;
            }
            else
            {
                visit[i++]=true;
                flag^=1;
                sum++;
            }
        }   
    }
    for(i=1;i<=N;i++)
    if(!visit[i])
    {
        printf("%d",i);
        return 0;
    }
    return 0;
}

<二>、对高精度数的划分

//高精度除法与减法(对二除法)
#include<stdio.h>
#include<string.h>
int main()
{
    char s[105]; 
    char s1[100];
    char p1[105];
    char p2[105];
    int i;
    gets(s);
    strcpy(s1,s);
    for(i=0;i<=strlen(s)-1;i++)
    {

        p1[i]=(s[i]-'0')/2+'0';
        if((s[i]-'0')%2!=0&&i!=strlen(s)-1)
        s[i+1]+=10;
    }
    p1[i]='\0';
    for(i=strlen(s1)-1;i>=0;i--)
    {
        if(s1[i]>=p1[i])
        p2[i]=s1[i]-p1[i]+'0';
        else
        {
            s1[i-1]--;
            s1[i]+=10;
            p2[i]=s1[i]-p1[i]+'0';
        }
    }
    p2[strlen(s1)]='\0';
    puts(p1);
    puts(p2);
    return 0;
} 

<三>、合并

#include<stdio.h>
#include<stdbool.h>
#include<string.h>
#include<stdlib.h>
char s[105];
int find(int num)
{
    int i;
    int flag=1;
    int sum=0;
    bool visit[100005];
    for(i=1;i<=num;i++)
    visit[i]=false;
    i=1;
    while(sum!=num-1)
    {
        if(i>num)
        i=1;
        if(visit[i])
        {
            i++;
            continue;
        }
        else
        {
            if(flag)
            {
                flag^=1;
                i++;
            }
            else
            {
                visit[i++]=true;
                flag^=1;
                sum++;
            }
        }   
    }
    for(i=1;i<=num;i++)
    if(!visit[i])
    return i;
}
int binary(char *str)
{
    if(strlen(str)>6)
    {
        char s[105]; 
        char p1[105];
        char p2[105];
        int i;
        int x,y;
        strcpy(s,str);
        for(i=0;i<=strlen(str)-1;i++)
        {
            p1[i]=(str[i]-'0')/2+'0';
            if((str[i]-'0')%2!=0&&i!=strlen(str)-1)
            str[i+1]+=10;
        }
        p1[i]='\0';
        for(i=strlen(s)-1;i>=0;i--)
        {
            if(s[i]>=p1[i])
            p2[i]=s[i]-p1[i]+'0';
            else
            {
                s[i-1]--;
                s[i]+=10;
                p2[i]=s[i]-p1[i]+'0';
            }
        }
        p2[strlen(s)]='\0';
        x=binary(p1);
        y=binary(p2);
        return x+y-1;
    }
    else
    return find(atoi(str));
}
int main()
{
    gets(s);
    printf("%d",binary(s));
    return 0;
}

不甘啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值