算法设计与分析 SCAU8598 整除15 问题

8598 整除15 问题

时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC;JAVA
在这里插入图片描述

Description

问题描述:
给定一个只包含数字[0…9]的字符串,求使用字符串中的某些字符,构建一个能够整除15的最大的整数。
注意,字符串中的每个字符只能使用一次。

编程任务:
求由给定字符串构建的能够整除15的最大整数。


输入格式

输入数据为一个只包含数字[0…9]字符串,字符串的长度为1~1000。

输出格式

将构建出的最大整数输出。

如果无法构建出能够整除15的整数,请输出 “impossible”

输入样例

02041


输出样例

4200


解题思路

按以下提示来慢慢构思算法即可
在这里插入图片描述



更多注释可查看下方的完整代码中,有助于理解。

代码如下
#include<iostream>
#include<math.h>
#include<algorithm>
#include<string>

using namespace std;

bool cmp(char a, char b){
    return a>b;
}

int main(){
    string str;
    int count = 0; //数字总和
    int ii = 0,numKK = 0;//ii判断有无0,1表示有,numKK计算5的个数。
    int x = 0, y = 0;//x 余1的个数,y余2的个数。
    cin>>str;
    for(int i = 0; i < str.size(); i++){
        if(str[i] == '0')
            ii = 1;
        if(str[i] == '5')
            numKK++;
        if((str[i] - '0') % 3 == 1)
            x++;
        else if((str[i] - '0') % 3 == 2)
            y++;
        count += (str[i] - '0');
    }

    if(ii || numKK){
        int min1 = 10, min2 = 10, min3 = 10;
        int i, j;
        int k, d;//记录两个待删下标。
        if(count % 3 == 1){
            //删除余1最小的。
            //若无余1,则删除余2最小的两个。
            if(str.size() == 1){
                cout<<"impossible"<<endl;
                return 0;
            }
            for(i = 0; i < str.size(); i++){
                int num = str[i] - '0';
                if((num % 3) == 1 && num < min1){
                    min1 = num;
                    j = i;
                }
            }
            if(min1 == 10){
                if(str.size() == 2 ){
                    cout<<"impossible"<<endl;
                    return 0;
                }
                //有0删两最小余2.
                if(ii){
                    for(i = 0; i < str.size(); i++){
                    int num = str[i] - '0';
                    if((num % 3) == 2){
                        if(min2 == 10){
                            min2 = num;
                            k = i;
                        }else if(min3 == 10){
                            min3 = num;
                            d = i;
                        }else{
                            if(min2 < min3){
                                k = i;
                                min2 = num;
                            }else{
                                d = i;
                                min3 = num;
                            }
                        }
                    }
                }
                    // cout<<"min2: "<<min2<<"min3: "<<min3<<endl;
                    str[k] = '0';
                    str[d] = '0';
                    sort(str.begin(), str.end(), cmp);
                    for(int w = 0; w < str.size() - 2; w++){
                        cout<<str[w];
                    }
                    cout<<endl;
                    return 0;
                }else{
                    if(y == 2){
                        cout<<"impossible"<<endl;
                        return 0;
                    }
                    //没有0,则最后留一个5,然后删两个最小余2。
                    for(int w = 0; w < str.size(); w++){
                        if((str[w] - '0') == 5){
                            swap(str[w], str[str.size() - 1]);
                            break;
                        }
                    }
                    for(i = 0; i < str.size() - 1; i++){
                    int num = str[i] - '0';
                    if((num % 3) == 2){
                        if(min2 == 10){
                            min2 = num;
                            k = i;
                        }else if(min3 == 10){
                            min3 = num;
                            d = i;
                        }else{
                            if(min2 < min3){
                                k = i;
                                min2 = num;
                            }else{
                                d = i;
                                min3 = num;
                            }
                        }
                    }
                }
                    // cout<<"min2: "<<min2<<"min3: "<<min3<<endl;
                    str[k] = '0';
                    str[d] = '0';
                    sort(str.begin(), str.end() - 1, cmp);
                    for(int w = 0; w < str.size() - 2; w++){
                        cout<<str[w];
                    }
                    cout<<str[str.size() - 1]<<endl;
                    return 0;
                }
            }else{
                for(int w = j + 1; w < str.size(); w++){
                    str[w - 1] = str[w];
                }
                str[str.size() - 1] = '0';
                sort(str.begin(), str.end(), cmp);
                for(int w = 0; w < str.size() - 1; w++){
                    cout<<str[w];
                }
                cout<<endl;
                return 0;
            }
        }else if(count % 3 == 2){
            //删除余2最小的。
            //若无余2,则删除余1最小的两个。
            if(str.size() == 1){
                cout<<"impossible"<<endl;
                return 0;
            }
            //如果只有一个5和一个其他余2的数,把5放最后,然后删掉那个余2的。
            //否则直接删除余2最小的。
            if(numKK == 1 && y == 2){
                int t;
                for(int w = 0; w < str.size(); w++){
                    if((str[w] - '0') == 5){
                        swap(str[w], str[str.size() - 1]);
                    }
                    if(((str[w] - '0') % 3 == 2) && (str[w] - '0') != 5){
                        t = w;
                    }
                }

                //覆盖t的值。
                for(i = t + 1; i < str.size(); i++){
                    str[i - 1] = str[i];
                }
                sort(str.begin(), str.end() - 2, cmp);
                for(i = 0; i < str.size() - 1; i++){
                    cout<<str[i];
                }
                cout<<endl;
                return 0;
            }else{
                //直接删除余2最小的。
                for(i = 0; i < str.size(); i++){
                    int num = str[i] - '0';
                    if((num % 3) == 2 && num < min1){
                        min1 = num;
                        j = i;
                    }
                }
            }

            //说明没有余2的数。直接删除两个最小余1的。
            if(min1 == 10){
                if(x <= 2){
                    cout<<"impossible"<<endl;
                    return 0;
                }

                for(i = 0; i < str.size(); i++){
                    int num = str[i] - '0';
                    if((num % 3) == 1){
                        if(min2 == 10){
                            min2 = num;
                            k = i;
                        }else if(min3 == 10){
                            min3 = num;
                            d = i;
                        }else{
                            if(min2 < min3){
                                k = i;
                                min2 = num;
                            }else{
                                d = i;
                                min3 = num;
                            }
                        }
                    }
                }
                    // cout<<"min2: "<<min2<<"min3: "<<min3<<endl;
                    str[k] = '0';
                    str[d] = '0';
                    sort(str.begin(), str.end(), cmp);
                    for(int w = 0; w < str.size() - 2; w++){
                        cout<<str[w];
                    }
                    cout<<endl;
                    return 0;

            }else{
                //将j位置的元素删除,输出。
                for(int w = j + 1; w < str.size(); w++){
                    str[w - 1] = str[w];
                }
                str[str.size() - 1] = '0';
                sort(str.begin(), str.end(), cmp);
                for(int w = 0; w < str.size() - 1; w++){
                    cout<<str[w];
                }
                cout<<endl;
                return 0;
            }
        }

        //如果没有0,则5放最后,其他排序输出。
        if(ii == 0){
            int flag = 0;
            for(int i = 0; i < str.size(); i++){
                if((str[i] - '0') == 5){
                    flag = 1;
                    swap(str[i], str[str.size() - 1]);
                    break;
                }
            }
            if(flag){
                sort(str.begin(), str.end() - 1, cmp);
                cout<<str<<endl;
            }else{
                cout<<"impossible"<<endl;
            }
        }else{
            sort(str.begin(), str.end(), cmp);
            cout<<str<<endl;
        }
    }else{
        cout<<"impossible"<<endl;
    }

    return 0;
}


最后

对我感兴趣的小伙伴可查看以下链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值