RC-u3 势均力敌
题目描述:
用 n>2 个不同的个位数字组成一个 n 位数,显然有 n! 个不同的结果。可以证明,这 n! 个数字可以被分为势均力敌的两组 —— 即平方和相等、且个数也相等的两组。
本题就请你用程序验证一下这个结论。
因为本题是一道简单题,所以规模很小,只考虑 n≤4 的情况。
输入格式:
输入第一行给出正整数 n(2<n≤4),随后一行给出 n 个不同的、在区间 [1, 9] 内的个位数字,其间以空格分隔。
输出格式:
将所有组成的 n! 个不同的 n 位数分为平方和相等、且个数也相等的两组。但你只需要输出其中一组就可以了。每个数字占一行,共输出 n!/2 行。
注意:解可能不唯一,输出任何一组解就可以。
输入样例:
3
5 2 1
输出样例:
125
512
251
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int a[10010], n;
vector<int> v;
bool st[10010];
int ans = 0;
int op = 0;
int p[10010];
bool flag;
void dfs(int u)//找到所有可组合出来的数
{
if (u == n) v.push_back(ans);
for (int i = 0; i < n; i++)
{
if (!st[a[i]])
{
int k = ans;
ans = ans * 10 + a[i];
st[a[i]] = true;
dfs(u + 1);
ans = k;
st[a[i]] = false;
}
}
}
void dfs1(int u, int h,int k,int xp)//暴力枚举一半数直到合法输出
{
if(flag) return;
if(u>=h)
{
if(xp==op-xp)
{
for(int i=0;i<h;i++)
{
cout<<p[i]<<endl;
}
flag = true;
}
return ;
}
for(int i=k;i<v.size();i++)
{
if(!st[v[i]])
{
p[u]=v[i];
st[v[i]]=true;
dfs1(u+1,h,i+1,xp+p[u]*p[u]);//注意这里是i+1,不是k+1
st[v[i]]=false;
p[u]=0;
}
}
}
int main()
{
cin >> n;
int sum = 1;
for (int i = n; i > 0; i--) sum *= i;
int h = sum / 2;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
dfs(0);
for (int i = 0; i < v.size(); i++)
{
op += v[i] * v[i];
}
memset(st, false, sizeof st);
dfs1(0, h,0,0);
return 0;
}
//125 512 251
//215 521 152