凑平方数

把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. .net core 使用SignalR实现实时通信

    这几天在研究SignalR,网上大部分的例子都是聊天室,我的需求是把服务端的信息发送给前端展示.并且需要实现单个用户推送. 用户登录我用的是ClaimsIdentity,这里就不多解释,如果不是很了解 ...

  2. mac tar 解压

    1.下载mac上对应rar版本 http://www.rarlab.com/download.htm2.利用tar名解压下载的rarosx-5.4.0.tar.gz,版本可能会更新tar xzvf a ...

  3. SUPPA 可变剪切分析

      SUPPA是一款通过转录本定量来获取可变剪切定量结果的软件.转录本的定量方式有很多,例如count,FPKM, TPM等,作者建议使用TPM,因为先均一化了基因的长度,然后均一化了测序的深度.同时 ...

  4. 如何使用C++实现单链表

    线性表--链表 为什么假期也在发文章 //TODO NullGirlfrindException 请忽略以上两行无聊的事实...... 如何弥补顺序表的不足之处? 第一次学习线性表一定会马上接触到一种 ...

  5. CentOS 7 下安装 MySQL 5.7

    从 CentOS 7 系统开始,MariaDB 成为 yum 源中默认的数据库安装包.在 CentOS 7 及以上的系统中使用 yum 安装 MySQL 包将无法使用 MySQL.您可以选择使用完全兼 ...

  6. 剑指offer31:整数中1出现的次数(从1到n整数中1出现的次数)

    1 题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙 ...

  7. golang之结构体使用注意事项和细节

    1. 结构体的所有字段在内在中是连续的 2. 结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(名字.个数和类型) 3. 结构体进行type重新定义(相当于取别名),Golang认 ...

  8. 二十一、RTC驱动

    一.RTC设备驱动分析 内核的rtc驱动位于内核drivers/rtc目录下,里面包含各个平台的RTC驱动.读者可在此目录下任意选择一个单板驱动文件进行分析,我选择的是rtc-davinci.c文件. ...

  9. centos7安装oracle11g(根据oracle官方文档安装,解决图形界面安装问题)

    一.系统及安装包 操作系统:centos 7.4 oracle版本:oracle 11g r2 二.centos环境配置 安装数据库所需要的软件包 [root@localhost data]# yum ...

  10. 怎样让ssh连接保持连接, 而不会因为没有操作而中断

    因为安全方面的考虑, ssh服务默认在一段时间内不操作会断开连接, 解决方法修改ssh的配置文件, 让ssh每隔一段时间就自动进行一次连接, 以达到保持连接的目的. 首先找到ssh配置文件的位置: f ...