您的位置:首页 > 其它

2016年第七届 蓝桥杯 全国总决赛B题(完全平方数)

2016-06-03 22:44 736 查看
题目意思就是:

给你0,1,2,3,4,5,6,7,8,9十个数字,要你选出任意一个或几个组合在一起成为完全平方数,每个数字都必须选且只能选一次,求可能的方案。

比如有其中几种符合题意的情况:

0 16 25 73984

0 1 625 73984

0 4 16 537289

0 16 784 5329

0 25 784 1936

ans=300;

#include<iostream>
using namespace std;
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
typedef long long ll;
const ll inf=(ll)(0x3f3f3f3f);
int ans=0;
ll t[105];
vector<ll> vec[500];
int len=0;
ll b[15];

int lens[600];
const int maxn=900005;
ll pri[maxn];
bool judge(ll x) {
ll o1=(ll)(sqrt(x));
return o1*o1==x;
}
void solve(ll *a,int num) {

memset(b,inf,sizeof(b));
int u=0,pos=0;
bool is=true;
for(int i=0; i<num; ++i) {
ll s=0;
if(!a[pos]&&t[i]>1) {
is=false;
break;
}
for(int j=pos; j<t[i]+pos; ++j) {
s=s*10+a[j];
}
b[u]=s;
++u;
pos=t[i]+pos;
}
if(is) {
sort(b,b+u);
bool issame=true;
for(int i=0; i<len; ++i) {
int sj=lens[i];
if(sj!=u)continue;
bool same1=true;
for(int j=sj-1; j>=0; --j) {
if(vec[i][j]!=b[j]) {
same1=false;
break;
}
}
if(same1) {
issame=false;
break;
}
}//判重
if(issame) {
++len;
lens[len-1]=u;
for(int i=0; i<u; ++i) {
vec[len-1].push_back(b[i]);
//                cout<<b[i]<<" ";
}
//            cout<<endl;
++ans;

}
}
}

ll ppp=(ll)maxn;
void dfs(ll *a,int sum,int num,int pos) {
if(!sum) {
solve(a,num);
} else if(sum<0);
else {
for(int i=sum; i>=1; --i) {//求划分数
t[num]=i;
ll ts=0;
bool can=true;
if(i>1&&a[pos]==0)continue;
for(int j=pos; j<pos+i&&can; ++j) {
ts=ts*10+a[j];
}
if((ts<ppp&&(!pri[ts]))||!judge(ts))continue;//剪枝
dfs(a,sum-i,num+1,pos+i);
}
}
}

int main() {
ll a[]= {0,1,2,3,4,5,6,7,8,9};
for(int i=0; i<500; ++i)
vec[i].clear();

for(ll i=0; i<ppp; ++i) {
pri[i]=judge(i);
}
int op=0;
do {
dfs(a,10,0,0);
} while(next_permutation(a,a+10));

cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: