您的位置:首页 > 其它

Codeforce 248B Chilly Willy

2012-11-26 21:22 169 查看
题目链接:

http://codeforces.com/problemset/problem/248/B



题目大意:

给一个n,求最小的n位数,使这个数能同时被2,3,5,7整除。其中1<=n<=10^5.

解题思路:

分析知这个数个位一定为零,因为它要同时被2和5整除,而一个数是否能被7整除取决于该数去掉最后一位的数减去最后一位的数的2倍的差能否被7整除。所以只需看去掉最后一位的数能否被7整除,所以倒数第二位一定为0,1,2,3,4,5,6其中之一,然后再分析这个数能否被3整除,如果所有位数之和能被3整除,则直接得出结果,如果被3整除余1,则加14(能同时满足被3,7整除),如果被3整除余2,则加7,也能满足要求。

判断一个数能否被7整除,可以通过去掉最后一位后减去最后一位的2倍能否被7整除来判断,但考虑到本题的特殊性,中间有一连串的0,而10……0被7除的余数与零的个数有周期性规律left[0]=1,left[1]=3,left[2]=2,left[3]=6,left[4]=4,left[5]=5,.……再left[i]表示有中间有i个零除以7后的余数,连上倒数第二位要求能被7整除则sumleft[1]=4,sumleft[2]=1,sumleft[3]=5,sumleft[4]=2,sumleft[5]=6,sumleft[6]=3,sumleft[i]表示当前面余数为i时的倒数第二的数的值,这样凑后一定能被7整除。



详见代码:

#include <iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>

using namespace std;

int main()
{
    int n;
    int left[6]={1,3,2,6,4,5};
    int sumleft[7]={0,4,1,5,2,6,3};

   while(scanf("%d",&n)!=EOF)
    {
        if(n==1||n==2)
        {
            printf("-1\n");
            continue;
        }
        a[1]=1;
        for(int i=2;i<=n;i++)
            a[i]=0;        //初始化过程
 	           
        int temp=(n-3)%6;
        a[n-1]=sumleft[left[temp]];   //temp表示中间零的个数,sumleft[i]表示当前面余数为i时的最后一位数的值使数能被7整除
        if((a[n-1]+1)%3==1)
        {
            a[n-1]+=4;
            a[n-2]+=1;
            if(a[n-1]>9)
            {
                a[n-1]-=10;
                a[n-2]++;
            }

        }
        else if((a[n-1]+1)%3==2)
        {
            a[n-1]+=7;
            if(a[n-1]>9)
            {
                a[n-1]-=10;
                a[n-2]++;
            }
        }

        for(int i=1;i<=n;i++)
            printf("%d",a[i]);
        putchar('\n');
    }

    return 0;
} 
--------------------------------------------------------------------------------

→Judgement Protocol
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: