POJ 1416 题解

题目地址

这是地址

AC代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>

using namespace std;

int mark[1000010];
int ans[6];
long long int numA,numB;

void dfs(int *list,string obj,int size,int now,int before,int num){
    list[now]=num;
    long long int sum=0,temp=obj[0]-'0';
    for (int i = 1; i < size; ++i) {
        if(list[i]==list[i-1]){
            temp*=10;
            temp+=obj[i]-'0';
        }else{
            sum+=temp;
            temp=obj[i]-'0';
        }
        if(i==size-1)sum+=temp;
    }
    if(sum<=numA&&sum>=numB){
        numB = sum;
        mark[numB]++;
        memcpy(ans,list, sizeof(ans));
    }
    if(now!=size-1)dfs(list,obj,size,size-1,now,num+1);
    if(now!=before+1)dfs(list,obj,size,now-1,before,num);
    list[now]=num-1;
    if(before == 0&&now==size-1){
        sum=0,temp=obj[0]-'0';
        for (int i = 1; i < size; ++i) {
            if(list[i]==list[i-1]){
                temp*=10;
                temp+=obj[i]-'0';
            }else{
                sum+=temp;
                temp=obj[i]-'0';
            }
            if(i==size-1)sum+=temp;
        }
        if(sum<=numA&&sum>=numB){
            numB = sum;
            mark[numB]++;
            memcpy(ans,list, sizeof(ans));
        }
    }

}

int main() {
    ios::sync_with_stdio(false);
    string a,b;
    while(cin>>a>>b,a!="0"&&b!="0"){
        if(a==b||a.length()>b.length())cout<<b<<" "<<b<<endl;
        else if(a.length()<=b.length()){
            numA=0,numB=0;
            for (int i = 0; i < a.length(); ++i) {
                numA*=10;
                numA+=a[i]-'0';
            }
            for (int j = 0; j < b.length(); ++j) {
                numB+=b[j]-'0';
            }
            if(numA<numB){
                cout<<"error"<<endl;
                continue;
            }
            if(b.size()==1){
                cout<<b<<" "<<b<<endl;
                continue;
            }
            int list[6];
            for (int k = 0; k < 6; ++k) {
                list[k]=1;
            }
            numB=1;
            memset(mark,0, sizeof(mark));
            dfs(list,b,b.length(),b.length()-1,0,2);
            if(mark[numB]!=1)cout<<"rejected"<<endl;
            else{
                cout<<numB<<' '<<b[0];
                for (int i = 1; i < b.size(); ++i) {
                    if(ans[i]!=ans[i-1])cout<<' ';
                    cout<<b[i];
                }
                cout<<' '<<endl;
            }
        }
    }
    return 0;
}

题解和题目思路

这道题被放到了剪枝里面去,但是仔细想想,搜索的规模也不大,直接DFS过去也不是问题。
我将要处理的字符串中的元素进行分类,初始情况为全部都为一类(不切),拿123456这个字符串举例,初始情况为111111,然后从最后一位开始,每次DFS都更改其中的一位,分为两种情况:

情况一:更改当前子串当前位下一位的分类,例如111112改为111122
情况二:如果当前位不是最后一位,更改新字串中的最后一位为下一类,以上面111122中的22为例,将其改为23

然后每一次DFS以后都计算当前分类情况下的数值,观察其是否满足条件并且大于等于当前已有的最大值,如果满足,就记录当前的分类情况至ans[]中以便输出,并且在对应的mark[]处加一以便判断是否存在重复的情况

其中有几种可以特判的情况请注意下,一是A>=B;二是在一的基础上,B的每一位单独加起来都大于A;三是在二的基础上,如果B为个位数则可以直接输出

DFS一定要确保能够搜索到所有的情况,漏了的话很可能导致WA,例如我原来就漏了不切的初始情况(扶额),下次注意

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
POJ3635是一道经典的数学题,需要使用一些数学知识和算法进行解决。 题目描述: 给定四个正整数 a、b、p 和 k,求 a^b^p mod k 的值。 解题思路: 首先,我们可以将指数 b^p 写成二进制形式:b^p = c0 * 2^0 + c1 * 2^1 + c2 * 2^2 + ... + ck * 2^k,其中 ci 为二进制数的第 i 位。 然后,我们可以通过快速幂算法来计算 a^(2^i) mod k 的值。具体来说,我们可以用一个变量 x 来存储 a^(2^i) mod k 的值,然后每次将 i 加 1,如果 ci 为 1,则将 x 乘上 a^(2^i) mod k,最后得到 a^b^p mod k 的值。 代码实现: 以下是 Java 的代码实现: import java.util.*; import java.math.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); BigInteger a = sc.nextBigInteger(); BigInteger b = sc.nextBigInteger(); BigInteger p = sc.nextBigInteger(); BigInteger k = sc.nextBigInteger(); BigInteger ans = BigInteger.ONE; for (int i = 0; i < p.bitLength(); i++) { if (b.testBit(i)) { ans = ans.multiply(a.modPow(BigInteger.ONE.shiftLeft(i), k)).mod(k); } } System.out.println(ans); } } 其中,bitLength() 函数用于获取二进制数的位数,testBit() 函数用于判断二进制数的第 i 位是否为 1,modPow() 函数用于计算 a^(2^i) mod k 的值,multiply() 函数用于计算两个 BigInteger 对象的乘积,mod() 函数用于计算模数。 时间复杂度: 快速幂算法的时间复杂度为 O(log b^p),其中 b^p 为指数。由于 b^p 的位数不超过 32,因此时间复杂度为 O(log 32) = O(1)。 总结: POJ3635 是一道经典的数学题,需要使用快速幂算法来求解。在实现时,需要注意 BigInteger 类的使用方法,以及快速幂算法的细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值