C - Select Mul

Time Limit: \(2\; sec\) / Memory Limit: \(1024\; MB\)

Score : \(300\; points\)

Problem Statement|题目描述

  • You are given an integer \(N\). Consider permuting the digits in \(N\) and separate them into two positive integers.

  • 对于一个整数 \(N\) ,考虑把 \(N\) 中的数字置换并分隔使其成为两个正整数

  • For example, for the integer \(123\), there are six ways to separate it, as follows:

\(12\) and \(3\),
\(21\) and \(3\),
\(13\) and \(2\),
\(31\) and \(2\),
\(23\) and \(1\),
\(32\) and \(1\).

  • 例如,对于整数 \(123\) ,有六种方法将其置换并分隔,如下所示:

\(12\)\(3\),
\(21\)\(3\),
\(13\)\(2\),
\(31\)\(2\),
\(23\)\(1\),
\(32\)\(1\).

  • Here, the two integers after separation must not contain leading zeros. For example, it is not allowed to separate the integer \(101\) into \(1\) and \(01\). Additionally, since the resulting integers must be positive, it is not allowed to separate \(101\) into \(1\) and \(0\), either.

  • 这里请注意,分离后的两个整数不能包含前导零。例如,不允许将整数 \(101\) 分为 \(1\)\(01\) 。此外,由于结果整数必须为正,因此也不允许将 \(101\) 分为 \(11\)\(0\)

Constraints|数据范围

  • \(N\) is an integer between \(1\) and \(10^9\) (inclusive).

  • \(N\) contains two or more digits that are not \(0\).

  • \(N\) 是介于 \(1\)\(10^9\)(包括在内)之间的整数。

  • \(N\) 包含两个或多个非 \(0\) 的数字

Input|输入

  • Input is given from Standard Input in the following format:
    N

  • 输入为以下格式的标准输入:
    N

Output|输出

  • Print the maximum possible product of the two integers after separation.

  • 输出分离后两个整数可能的最大乘积。

Sample Input 1 |样例输入 1

123

Sample Output 1 |样例输出 1

63

  • As described in Problem Statement, there are six ways to separate it:

\(12\) and \(3\),
\(21\) and \(3\),
\(13\) and \(2\),
\(31\) and \(2\),
\(23\) and \(1\),
\(32\) and \(1\).

  • 如题目描述中所述,有六种方法将其分开:

\(12\)\(3\),
\(21\)\(3\),
\(13\)\(2\),
\(31\)\(2\),
\(23\)\(1\),
\(32\)\(1\).

  • The products of these pairs, in this order, are \(36\), \(63\), \(26\), \(62\), \(23\), \(32\), with \(63\) being the maximum.

  • 按此顺序,这些对的乘积是 \(36\)\(63\)\(26\)\(62\)\(23\)\(32\),其中 \(63\) 是最大值。

Sample Input 2 |样例输入 2

1010

Sample Output 2 |样例输出 2

100

  • There are two ways to separate it:

\(100\) and \(1\),
\(10\) and \(10\).

  • 有两种方法可以将其拆分:

\(100\)\(1\)
\(10\)\(10\)

  • In either case, the product is \(100\).

  • 无论哪种情况,乘积都是 \(100\)

Sample Input 3 |样例输入 3

998244353

Sample Output 3 |样例输出 3

939337176


分析

这道题还挺简单的,时限两秒,于是写了个 \(DFS\)(在CCF上这么干估计会被锤)

先开了一个数组 \(a\) , \(a_i\)表示数字\(i(0\leq i\leq 9)\)\(N\) 中出现的次数。
然后搜索无限的可能…

inline void input(){
	char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){
		a[ch-'0']++;
		n++;
		ch=getchar();
	}
}

\(x,y\) 分别表示两个正整数,对于 \(a_i\neq 0\) ,更新 \(a_i\) ,依次选择将 \(i\) 加入到 \(x\)\(y\) 的下一位,然后回溯:

for(int i=1;i<=9;i++){
	if(!a[i])continue;
	a[i]--;
	x*=ten;x+=i;dfs(k+1);x/=ten;
	y*=ten;y+=i;dfs(k+1);y/=ten;
	a[i]++;
}

特别的,如果 \(i=0\),想要添加需满足 \(x\neq 0\) 或者 \(y\neq 0\)

if(x&&a[0]){
	a[0]--;
	x*=ten;dfs(k+1);x/=ten,a[0]++;
}if(y&&a[0]){
	a[0]--,y*=ten;
	dfs(k+1);
	y/=ten,a[0]++;
}

AC代码:

#include<bits/stdc++.h>
typedef long long ll;
const ll ten=10;
int a[12];
int n;
ll x,y;
ll ans;
inline ll mymax(ll fir,ll sec){return fir>sec?fir:sec;}
inline void input(){
	char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){
		a[ch-'0']++;
		n++;
		ch=getchar();
	}
}
inline void dfs(int k){
	if(k==n){
		ans=mymax(ans,x*y);
		return ;
	}
	if(x&&a[0]){
		a[0]--;
		x*=ten;dfs(k+1);x/=ten,a[0]++;
	}if(y&&a[0]){
		a[0]--,y*=ten;
		dfs(k+1);
		y/=ten,a[0]++;
	}
	for(int i=1;i<=9;i++){
		if(!a[i])continue;
		a[i]--;
		x*=ten;x+=i;dfs(k+1);x/=ten;
		y*=ten;y+=i;dfs(k+1);y/=ten;
		a[i]++;
	}
}
int main(){
	input();
	dfs(0);
	printf("%lld",ans);
	return 0;
} 
$$-----CONTINUE-----$$

< last 「ABC221B」typo 题解
> next 「ABC221D」Online games 题解

> catalogue 「ABC221」题解