C. 排列与合数
Problem
小 A 在 2023 年河南省 CCPC 大学生程序设计竞赛的赛场上遇到了一道名为"排列与质数"的题目。与大多数选手一样,小 A 并没能在赛场上解决这个棘手的题目。比赛结束后,小 A 想到了一个与之相关的题目:排列与合数,可是小 A 仍然没有能力解决。这个名为"排列与合数"的题目是这样的:
给定一个有且仅有 5 位,且各个数位互不相同的十进制正整数 n。你可以重新排列 n 的各个数位,但需要保证重新排列得到的整数 n’ 没有前导零。请问重新排列数位得到的 n’ 能否为合数?若能为合数,请求出一个满足条件的 n’。
例如,当 n = 12345 时,任意排列得到的 n’ 均是合数,因此可以任意取 n’。当 n = 13579 时,可以重新排列数位得到合数 n’ = 97531 = 7 × 13933。
一个正整数是合数,当且仅当它可以分解为两个不小于 2 的整数的乘积。
现在,小 A 带着他的题目来到赛场上求助。你能帮助小 A 解决这个题目吗?
Input
本题测试点包含多组数据。
第一行,一个正整数 T T T ( 1 ≤ T ≤ 1 0 5 ) (1 ≤ T ≤ 10^5) (1 ≤ T ≤ 105),表示数据组数。
对于每组数据:
一行,一个正整数 n n n( 1 0 4 ≤ n < 1 0 5 ) 10^4 ≤ n < 10^5) 104 ≤ n < 105),保证 n 的各个数位互不相同。
Output
对于每组数据:
输出一行,一个整数。若能重新排列 n 的数位得到合数 n’ 则输出 n’,否则输出 - 1。
Example
Input
5
12345
12345
12345
12345
13579
Output
12345
54321
13524
45123
97531
```
## Note
样例即是题目描述中给出的例子。
## Code
```cpp
// #include <iostream>
// #include <algorithm>
// #include <cstring>
// #include <stack>//栈
// #include <deque>//堆/优先队列
// #include <queue>//队列
// #include <map>//映射
// #include <unordered_map>//哈希表
// #include <vector>//容器,存数组的数,表数组的长度
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p[6],v[10];
bool f;
ll find(ll x)
{
for(ll i=2;i*i<=x;i++)
{
if(x%i==0) return 1;
}
return 0;
}
void dfs(ll u)
{
if(f) return;
if(u>5)//数字填完即输出
{
ll sum=0,op=1;
for(ll i=5;i>0;i--)
{
sum+=p[i]*op;
op*=10;
}
if(find(sum))
{
f=1;
cout<<sum<<endl;
return;
}
}
for(ll i=1;i<10;i++)//空位:1 ~ n
{
if(!v[i])//如果数字 i 没有被用过
{
p[u]=i;//放入空位
v[i]=1;//数字被用,修改状态
dfs(u+1);//填下一个位
v[i]=0;//回溯,取出 i
}
}
}
void solve()
{
string s;
cin>>s;
f=0;
memset(p,0,sizeof p);
memset(v,1,sizeof v);
ll op=-1;
for(ll i=0;i<s.size();i++)
{
v[s[i]-'0']=0;
if(s[i]=='0') op=i;
}
if(op!=-1)
{
cout<<s.substr(0,op)<<s.substr(op+1,s.size()-op-1)<<0<<endl;
return;
}
dfs(1);
if(!f) cout<<-1<<endl;
}
int main()
{
ll t;
cin>>t;
while(t--) solve();
return 0;
}
```