凑平方数

把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. synchronized的不足与redis分布式锁的使用

    这里是一个简单模拟秒杀的逻辑,stock和orders为两个Map,分别模拟库存表和订单表 public void orderProductMockDiffUser(String productId) ...

  2. oracle的jdbc的版本与jdk对应关系

    连接类型:1. JDBC OCI: oci是oracle call interface的缩写,此驱动类似于传统的ODBC 驱动.因为它需要Oracle Call Interface and Net8, ...

  3. MyBatis逆向工程生成配置 generator (生成pojo、mapper.xml、mapper.java)

    MyBatis逆向工程生成 mybatis需要程序员自己编写sql语句,mybatis官方提供逆向工程,可以针对单表自动生成mybatis执行所需要的代码(mapper.java.mapper.xml ...

  4. PyCharm:设置py文件头部信息

    P PyCharm:设置py文件头部信息file->setting->appearance & behavior->editor->file and code temp ...

  5. golang使用一个二叉树来实现一个插入排序

    思路不太好理解,请用断点 package main import "fmt" type tree struct { value int left, right *tree } fu ...

  6. python pip命令安装相当于yum仓库

    进入pip目录: 创建pip.conf: 打开pip.conf [global] index-url=https://mirrors.aliyun.com/pypi/simple/ trusted-h ...

  7. High load average analyze

    https://www.tummy.com/articles/isolating-heavy-load/ https://www.tecmint.com/understand-linux-load-a ...

  8. (未完成)ARM-linux 移植 SDL

    ref : https://blog.csdn.net/u012075739/article/details/24877639   2.      交叉编译SDL 编译SDL前先要编译其依赖库 tsl ...

  9. 题解-APIO2019桥梁

    problem \(\mathrm {loj-3145}\) 题意概要:给定一张 \(n\) 点 \(m\) 边的无向图,边有边权,共 \(q\) 次操作,每次会将第 \(x\) 条边的权值改为 \( ...

  10. glance

    第二篇glance— 镜像服务 一.glance介绍:              Glance是Openstack项目中负责镜像管理的模块,其功能包括虚拟机镜像的查找.注册和检索等. Glance提供 ...