思路:
刚开始暴力枚举,33分,优化一下,66分。
再优化,还是有组数据TLE。网上有份 java 代码,改成 C++ 后终于100了!
还是方法有问题,以小见大,不同的方法做事,会有不同的结果。当一种办法行不通时,改变一下思路,或许就有了答案。
dfs + 剪枝:
首先,暴力 1 - 9 的全排列,假设其中一个为 246517983,n = 100
我们令 N = n1 + n2 / n3,则 n1 的截取终点 Rn1 取值:1 - lenN (N 的长度)
然后,若 n1 取24,则 n2 的截取终点 Rn2 取值:Rn1 + ( 10 - Rn1 ) / 2 - 8
最后,判断是否符合条件就OK了!
代码:
#include <stdio.h>
#include <iostream>
#include <cstring>
using namespace std ;
int a[ 15 ] , vis[ 15 ] , cnt , lenN ;
int sum( int Left , int Right ) //将 a[Left - Right] 转换为整数
{
int s = 0 ;
for( int i = Left ; i <= Right ; i++ ) s = 10 * s + a[ i ] ;
return s ;
}
void dfs( int L , int sn , int N )
{
int n1, n2 , n3 , Rn1 , Rn2 ;
if( L == sn ) { //若已经生成一个全排列
for( Rn1 = 1 ; Rn1 <= lenN ; Rn1++ ) {
n1 = sum( 1 , Rn1 ) ; //n1 取 a[1 - Rn1]
if( n1 >= N ) return ; //不符合,剪枝
for( Rn2 = Rn1 + ( 10 - Rn1 ) / 2 ; Rn2 < 9 ; Rn2++ ) {
n2 = sum( Rn1 + 1 , Rn2 ) ;
n3 = sum( Rn2 + 1 , 9 ) ;
if( n2 >= n3 && n2 % n3 == 0 && N == n1 + n2 / n3 ) cnt++ ;
}
}
}
else {
for( int i = 1 ; i <= 9 ; i++ ) { //全排列,下面与小白书127页素数环类似
if( vis[ i ] ) continue ; //若 i 已经用过,结束本次循环,判断下一个
a[ L ] = i ; //i 没用过,将当前数字设置为 i
vis[ i ] = 1 ; //标记
dfs( L + 1 , sn , N ) ; //设置下一个数字
vis[ i ] = 0 ; //清除标记
}
}
}
int main()
{
int N ;
scanf( "%d" , &N ) ;
int tN = N ;
while( tN ) {
lenN++ ; // lenN 为 N 的长度
tN /= 10 ;
}
dfs( 1 , 10 , N ) ;
cout << cnt << endl ;
return 0 ;
}
这里我们还可以用C++里的STL生成全排列,就是一个循环,一个函数,so easy!
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std ;
int a[ 15 ] , vis[ 15 ] , cnt , lenN ;
int sum( int Left , int Right ) //将 a[Left - Right] 转换为整数
{
int s = 0 ;
for( int i = Left ; i <= Right ; i++ ) s = 10 * s + a[ i ] ;
return s ;
}
int main()
{
int N ;
int n1, n2 , n3 , Rn1 , Rn2 ;
scanf( "%d" , &N ) ;
int tN = N ;
while( tN )
{
lenN++ ; // lenN 为 N 的长度
tN /= 10 ;
}
for (int i = 1; i <= 9; i++) a[i] = i;
do
{
for( Rn1 = 1 ; Rn1 <= lenN ; Rn1++ ) {
n1 = sum( 1 , Rn1 ) ; //n1 取 a[1 - Rn1]
if( n1 >= N ) continue ; //不符合,继续下一个排列
for( Rn2 = Rn1 + ( 10 - Rn1 ) / 2 ; Rn2 < 9 ; Rn2++ ) {
n2 = sum( Rn1 + 1 , Rn2 ) ;
n3 = sum( Rn2 + 1 , 9 ) ;
if( n2 >= n3 && n2 % n3 == 0 && N == n1 + n2 / n3 ) cnt++ ;
}
}
} while (next_permutation(a + 1, a + 9 + 1));
cout << cnt << endl ;
return 0 ;
}