1095 Nikifor3

由于题目中说了数字中一定含有1,2,3,4. 所以我们可以推出输入的数字一定可以表示乘能被7整除的形式.
证明:

假设所给的数字中可以表示成: num_count[10]; 其中该数组表示为每个数字出现的个数.我们可将所需求得数表示成 num = N * 10000 + {1,2,3,4} + {0}; (其中N表示所给数中除去所有的0,和一个1,2,3,4,所组成的数可以任意组合 ; {1,2,3,4}表示其排列组合所可能的值, {0}表示0的个数)
num % 7 = 0, 可表示为 ( (N*10000) % 7 + {1,2,3,4} % 7 ) % 7 = 0 . 我们可知由{1,2,3,4}所组成的数模7可以得到0~6任何一个数:

    4123 % 7 = 0        2134 % 7 = 6          1342 % 7 = 5
    1243 % 7 = 4        2341 % 7 = 3           1234 % 7 = 2       1324 % 7 = 1  

所以我们只要 根据 remain = (N * 10000) % 7, 找出相应的{1,2,3,4}所组成的数与其相加为7, 即可;

/*************************************************************************
  > File Name   : 1095Nikifor3.cpp
  > Author      : liudy
  > Mail        : 787896130@qq.com
  > Created Time: 2016年08月10日 星期三 14时03分35秒
 ************************************************************************/

#include<iostream>
#include<cstdio>
using namespace std;

int mod[7] = {4123, 2134, 1342, 1243, 2341, 1234, 1324};

int main(){
    int n;
    cin >> n;
    getchar();  //忽略输入n后的换行符
    for(int i = 0; i < n; i++){
        char c;
        int num = 0;
        int Num_count[10] = {0};  //用于记录每个数字出现的次数
        while(c = getchar()){
            if(c == '\n')
                break;
            Num_count[c - '0']++;    
        }
        Num_count[1]--; Num_count[2]--; 
        Num_count[3]--; Num_count[4]--;
        for(int j = 1; j < 10; j++){
            for(int k = 0; k < Num_count[j]; k++){
                num = (num * 10 + j) % 7;
                cout << j;
            }   
        }
        int remain = num * 10000 % 7;
        cout << mod[remain];
        for(int j = 0; j < Num_count[0]; j++)
            cout << 0;
        cout << endl;

    }

    return 0;
}

如果题目中并未说明所输入的数一定含有1,2,3,4. 我想的做法是对所给的数进行全排列也就是n!种可能的数都进行一次检测看其是否被7整除, 判断一个数能否被7整除采用的方法是:
截 尾 法 :

將 原 來 的 數 字 割 去 末 端 的 數 字

然 後 再 減 去 末 位 數 的 兩 倍

重 複 (1) 及 (2) 直 到 所 得 的 數 字 容 易 看 得 出 是 否 能 被 7 整 除


代码如下(但是该代码用于此题上交会出现WA10, 不知是什么bug, 望请指教)

/*************************************************************************
  > File Name   : 1095_Nikifor3.cpp
  > Author      : liudy
  > Mail        : 787896130@qq.com
  > Created Time: 2016年08月10日 星期三 10时19分18秒
 ************************************************************************/

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;

void Print_Array(int A[], int len){
    int Abegin = 0;
    while(!A[Abegin])
        Abegin++;
    for(int i = Abegin; i < len; i++)
        cout << A[i];
    cout << endl;
}
void Copy_Array(int A[], int B[], int len){
    for(int i = 0; i < len; i++){
        B[i] = A[i];
    }
}
int Array_to_num(int A[], int Abegin, int Aend){
    int num = 0;
    for(int i = Abegin; i <= Aend; i++){
        num = num * 10 + A[i];
    }
    return num;
}
void Num_to_Array(int num, int A[], int Abegin, int Aend){
    for(int i = Aend; i >= Abegin; i--){
        A[i] = num % 10;
        num /= 10;
    }
}
bool Sub(int A[], int len, int sub_num){
    int num, result;
    for(int i = len; i >= 0; i--){
        num = Array_to_num(A, i, len);
        if(num >= sub_num){
            result = num - sub_num;
            Num_to_Array(result, A, i, len);
            return true;
        }
    }
    return false;
}
bool check_divisible_By_7(int A[], int len){
    int num[25];
    Copy_Array(A, num, len);
    for(int i = len - 2; i >= 2; i--){
        int sub_num = num[i + 1] * 2;

    //    if(!Sub(num, i, sub_num)) 
     //       cout << "Error: Array value is less than sub_num!" << endl;   
         Sub(num, i, sub_num);
    }
    int remain = Array_to_num(num, 0, 2);
    if(remain % 7 == 0)
        return true;
    else
        return false;
}
int main(){
    int Array[25];
    int PreArray[25];
    int n;
    cin >> n;
    getchar();   //忽略输入n后, 输入的换行符
    for(int i = 0; i < n; i++){
        char c;
        int len = 0;
        bool flag = true;
        while(c = getchar()){
            if(c == '\n')
                break;
            else{
                Array[len++] = c - '0';
            }
        }
        Copy_Array(Array, PreArray, len);
        // sort(Array, Array+len);
        do{
            if(PreArray[0] == 0)
                break;
            if(check_divisible_By_7(PreArray, len)){
                Print_Array(PreArray, len);
                flag = false;
                break;
            } 
        }while(prev_permutation(PreArray, PreArray+len));
        if(flag)
            do{
                if(check_divisible_By_7(Array, len)){
                    Print_Array(Array, len);
                    flag = false; 
                    break;
                }
            }while(next_permutation(Array, Array+len));
        if(flag)
            cout << 0 << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值