凑平方数

把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721

再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...

注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。

如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

注意:需要提交的是一个整数,不要填写多余内容。


错误题解(答案错误原因未知、暴力五重for循环——超时,优化再优化超时!)——可供借鉴!

 #include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include<math.h>
#include <string.h>
#include<set>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 10000000
const double pi=acos(-1.0);
#define ll long long
#define N 100008
using namespace std;
vector<ll>a;
int getlen(ll x){// 返回x的数字位数
return (int)log10(x*1.0)+;
}
int cmp1(ll x){ //cmp1()表示传入的1个数是否没有重复数码
int arr[]={};
while(x>){
arr[x%]++;x/=;
}
for(int i=;i<=;i++)
if(arr[i]>)return ;
return ;
}
int cmp2(ll x,ll y){ //cmp2--5()表示传入的2--5个数是否可以不重不漏地构成十位数码
if(getlen(x)+getlen(y)>)
return ;
int arr[]={};
while(x>){
arr[x%]++;x/=;
}
while(y>){
arr[y%]++;y/=;
}
for(int i=;i<=;i++){
if(arr[i]>)return ;
else if(arr[i]==)return ;//缺省时
} return ; }
int cmp3(ll x,ll y,ll z){
if(getlen(x)+getlen(y)+getlen(z)>)
return ;
int arr[]={};
while(x>){
arr[x%]++;x/=;
}
while(y>){
arr[y%]++;y/=;
}
while(z>){
arr[z%]++;z/=;
}
for(int i=;i<=;i++){
if(arr[i]>)return ;
else if(arr[i]==)return ;//缺省时
}
return ;
}
int cmp4(ll x,ll y,ll z,ll h){
if(getlen(x)+getlen(y)+getlen(z)+getlen(h)>)
return ;
int arr[]={};
while(x>){
arr[x%]++;x/=;
}
while(y>){
arr[y%]++;y/=;
}
while(z>){
arr[z%]++;z/=;
}
while(h>){
arr[h%]++;h/=;
}
for(int i=;i<=;i++){
if(arr[i]>)return ;
else if(arr[i]==)return ;//缺省时
}
return ; }
int cmp5(ll x,ll y,ll z,ll h,ll t){//表示传入的五个数是否可以不重不漏地构成十位数码
if(getlen(x)+getlen(y)+getlen(z)+getlen(h)+getlen(t)>)
return ;
int arr[]={};
while(x>){
arr[x%]++;x/=;
}
while(y>){
arr[y%]++;y/=;
}
while(z>){
arr[z%]++;z/=;
}
while(h>){
arr[h%]++;h/=;
}
while(t>){
arr[t%]++;t/=;
}
for(int i=;i<=;i++){
if(arr[i]>)return ;
else if(arr[i]==)return ;//缺省时
}
return ; } int main(){ ll maxx=;//确定上限
int cnt=;
a.clear();
for(ll i=;i<=;i++){//筛选出制定范围内的所有平方数
if(i*i>maxx)break;
if(cmp1(i*i)==)////将自身数码不重复的平方数存入a中
a.push_back(i*i);
} cnt=a.size();
printf("总的平方数==%d %lld\n",cnt,a[cnt-]);//611 9814072356 int ans=;
for(int i=cnt-;i>=;i--){///把后面的十位数平方数全部删除掉
if(getlen(a[i])==){
ans++;a.pop_back();
}
else
break;
}
cnt=a.size();
printf("10位的平方数有ans=%d %d %lld\n",ans,cnt,a[cnt-]);//87,524
/*由于接下来只剩1--9位的平方数了,可以进行两两枚举、三三枚举、四四五五地枚举;
原先就是如下写的————
for(int i1=0;i1<cnt;i1++){
for(int i2=i1+1;i2<cnt;i2++){
if(cmp2(a[i1],a[i2])==1)
ans++;
}
}
for(int i1=0;i1<cnt;i1++){
for(int i2=i1+1;i2<cnt;i2++){
for(int i3=i2+1;i3<cnt;i3++){
if(cmp3(a[i1],a[i2],a[i3])==1)
ans++;
}
}
}
for(int i1=0;i1<cnt;i1++){
for(int i2=i1+1;i2<cnt;i2++){
for(int i3=i2+1;i3<cnt;i3++){
for(int i4=i3+1;i4<cnt;i4++){
if(cmp4(a[i1],a[i2],a[i3],a[i4])==1)
ans++;
}
}
}
}
for(int i1=0;i1<cnt;i1++){
for(int i2=i1+1;i2<cnt;i2++){
for(int i3=i2+1;i3<cnt;i3++){
for(int i4=i3+1;i4<cnt;i4++){
for(int i5=i4+1;i5<cnt;i5++){
if(cmp5(a[i1],a[i2],a[i3],a[i4],a[i5])==1)
ans++;
}
}
}
}
} */
//后来发现这其中有大量重复计算,在上面两两枚举中,若一对数有冲突仍会进行往下跑循环,
//再细想,发现三重循环实际上包含了两重循环,四重含三重和两重,五重......
//所以可以进行简单优化,continue,并且有了下面的四合一程序
int k;
printf("ans有:ans=%d\n",ans);
ll Time=;
for(int i1=;i1<cnt;i1++){
for(int i2=i1+;i2<cnt;i2++){
if(k=cmp2(a[i1],a[i2]),k==)
ans++;
if(k==||k==)//k=0有重复或者k=1找到答案,k==2表示缺省(可以向下搜),k==3表示总位数超10——break
continue;
if(k==)break;
for(int i3=i2+;i3<cnt;i3++){
if(k=cmp3(a[i1],a[i2],a[i3]),k==)
ans++;
if(k==||k==)//有重复或者已经全部使用过了
continue;
if(k==)break;
for(int i4=i3+;i4<cnt;i4++){
if(k=cmp4(a[i1],a[i2],a[i3],a[i4]),k==)
ans++;
if(k==||k==)//有重复或者已经全部使用过了
continue;
if(k==)break;
for(int i5=i4+;i5<cnt;i5++){
if(k=cmp5(a[i1],a[i2],a[i3],a[i4],a[i5]),k==)
ans++;
if(k==)break;
Time++;
if(Time%(ll)==)printf("%3d,%3d,%3d,%3d,%3d, Time=%5lld十万\n",i1,i2,i3,i4,i5,Time/(ll));
}
}
}
}
} printf("总ans有:ans=%d\n",ans);
return ;
}

计算一下时间复杂度,很重要!如果很大很大,就建议直接放弃,换种思路!


正确题解(一维搜索,可以有效降低时间复杂度,因为在一维数组a[]中,元素是递增的--元素的长度就是非递减的,一旦某一个因为长度超出后不合适——后续的都不合适了)。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include<math.h>
#include <string.h>
#include<set>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 10000000
const double pi=acos(-1.0);
#define ll long long
#define N 10008
using namespace std;
ll a[N]; int check(string num){//判断字符串num是否重复
int arr[]={};
int len=num.length();
for(int i=;i<len;i++){
int t=num[i]-'';
arr[t]++;
if(arr[t]>)return ;
}
return ;
}
string turn(ll num){//将num转化成字符串进行输出
string s;
if(num==)s+="";
while(num>){
char ch[]={num%+'','\0'};//临时字符串,用于string的插入
s.insert(,ch);
num/=;
}
return s;
}
int ans;//在a[]数组中进行一维搜索,每次选取step的位置,然后再往后选取一位合适的
void dfs(int step,string s,int cnt){ if(s.length()>||check(s)==)return ; if(s.length()==&&check(s)==){
ans++;
return ;
}
for(int i=step;i<=cnt;i++){
dfs(i+,s+turn(a[i]),cnt);
} }
int main(){ ll maxx=;
int cnt=;
for(ll i=;i<=;i++){//生成完全平方数表,共cnt个
if(i*i<=maxx){
if(check(turn(i*i)))
a[++cnt]=i*i;
}
else break;
}
printf("完全平方数cnt=%d\n",cnt);
ans=;
dfs(,"",cnt);
printf("%d\n",ans); return ;
}

【正确答案:300】

第七届蓝桥杯C/C++程序设计本科B组决赛 ——凑平方数(填空题)的更多相关文章

  1. 第七届蓝桥杯C/C++程序设计本科B组决赛 ——机器人塔(程序大题)

    机器人塔 X星球的机器人表演拉拉队有两种服装,A和B.他们这次表演的是搭机器人塔. 类似: A B B A B A A A B B B B B A BA B A B B A 队内的组塔规则是: A 只 ...

  2. 2016年第七届蓝桥杯C/C++程序设计本科B组决赛

    2.答案300 刁丝卫代码,比赛时long long写成int,结果成了263...一等擦肩而过... #include <iostream> #include <fstream&g ...

  3. 第七届蓝桥杯C/C++程序设计本科B组决赛 ——棋子换位(代码补全题)

    棋子换位 有n个棋子A,n个棋子B,在棋盘上排成一行.它们中间隔着一个空位,用“.”表示,比如: AAA.BBB 现在需要所有的A棋子和B棋子交换位置.移动棋子的规则是:1. A棋子只能往右边移动,B ...

  4. 2015年第六届蓝桥杯C/C++程序设计本科B组决赛 ——居民集会(编程大题)

    标题:居民集会 蓝桥村的居民都生活在一条公路的边上,公路的长度为L,每户家庭的 位置都用这户家庭到公路的起点的距离来计算,第i户家庭距起点的距 离为di.每年,蓝桥村都要举行一次集会.今年,由于村里的 ...

  5. 2016年第七届蓝桥杯C/C++程序设计本科B组省赛

    /* 2016年第七届蓝桥杯C/C++程序设计本科B组省赛 煤球数目(结果填空) 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形) ...

  6. 2015年第六届蓝桥杯C/C++程序设计本科B组决赛

    1.积分之谜(枚举) 2.完美正方形 3.关联账户(并查集) 4.密文搜索 5.居民集会 6.模型染色 1.积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C.为了促销,每件商品都会返固定 ...

  7. 2015年第六届蓝桥杯C/C++程序设计本科B组决赛 完美正方形

    完美正方形 如果一些边长互不相同的正方形,可以恰好拼出一个更大的正方形,则称其为完美正方形.历史上,人们花了很久才找到了若干完美正方形.比如:如下边长的22个正方形 2 3 4 6 7 8 12 13 ...

  8. 2016年第六届蓝桥杯C/C++程序设计本科B组决赛 ——一步之遥(填空题题)

    一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里.矿车停在平直的废弃的轨道上.他的面前是两个按钮,分别写着“F”和“B”. 小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退.按F,会 ...

  9. 第八届蓝桥杯C/C++程序设计本科B组决赛 ——发现环(编程大题_签到题_tarjan判环)

    标题:发现环 小明的实验室有N台电脑,编号1~N.原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络.在树形网络上,任意两台电脑之间有唯一的路径相连. 不过在最近一次维护网络时,管理员误操 ...

随机推荐

  1. Eureka客户端源码流程梳理

    前面梳理了Eureka服务端的流程,现在整理下客户端的流程. 1.在这个包(spring-cloud-netflix-eureka-client)里面寻找客户端启动入口相关配置,关键配置文件sprin ...

  2. LeetCode 53. 最大子序和(Maximum Subarray)

    53. 最大子序和 53. Maximum Subarray 题目描述 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. LeetCode53. M ...

  3. SQL语言(一)

    数据定义语言:简称DDL(Data Definition Language) create database 数据库名 character set 'utf-8'; drop database 数据库 ...

  4. [C++] 习题 2.15 实现简单环形队列

    目录 前置技能 环形队列 具体实现 设计一个环形队列,用front和rear分别作为队头和队尾指针,另外用一个tag表示队列是空 ( 0 ) 还是不空 ( 1 ),这样就可以用front==rear作 ...

  5. 09 IO流(六)——ByteArray字节流、流对接

    字节数组流 ByteArray流是节点流. 前面讲到的文件字节流,文件字符流,他们的源都是来自于pc硬盘. 本节要讲的字节数组流的源是来自于内存或网络. 它更合适用来处理来自网络的字节流. 由于源并不 ...

  6. Hibernate持久化,生命周期

    一 .生命周期   1.1  . 说明 持久化类就是我们所说的实体类,实体类(持久化类)对象是有状态的. 为什么实体类对象会有状态? 答:由于HIbernate框架是一个先映射,后操作的框架.所谓的状 ...

  7. Go context 介绍和使用

    context 上下文管理 context 翻译过来就是上下文管理,主要作用有两个: 控制 goroutine 的超时 保存上下文数据 WithTimeout 通过下面的一个简单的 http 例子进行 ...

  8. VS2015编译Teamtalk的Windows客户端(转)

    原文链接:https://blog.csdn.net/qtstar/article/details/54732581 一.(首先要把teamtalk整个项目download下来或git一个副本下来)打 ...

  9. 遇到 GLFW 我的demo可以运行 但是公司的程序调用我的so运行不起来

    //to do 原       因:  发现 自身demo的程序的shaders更新了  但是公司程序却没有更新 解决办法:更新公司程序的shaders 为最新版本 吸取的教训: 不仅仅要更新公司程序 ...

  10. php中需要注意的函数(持续更新)

    explode 函数 $a = null; explode("#",$a); //不会报错会返回一个只包含空字符串的数组