第七届蓝桥杯C/C++程序设计本科B组决赛 ——凑平方数(填空题)
凑平方数
把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组决赛 ——凑平方数(填空题)的更多相关文章
- 第七届蓝桥杯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 只 ...
- 2016年第七届蓝桥杯C/C++程序设计本科B组决赛
2.答案300 刁丝卫代码,比赛时long long写成int,结果成了263...一等擦肩而过... #include <iostream> #include <fstream&g ...
- 第七届蓝桥杯C/C++程序设计本科B组决赛 ——棋子换位(代码补全题)
棋子换位 有n个棋子A,n个棋子B,在棋盘上排成一行.它们中间隔着一个空位,用“.”表示,比如: AAA.BBB 现在需要所有的A棋子和B棋子交换位置.移动棋子的规则是:1. A棋子只能往右边移动,B ...
- 2015年第六届蓝桥杯C/C++程序设计本科B组决赛 ——居民集会(编程大题)
标题:居民集会 蓝桥村的居民都生活在一条公路的边上,公路的长度为L,每户家庭的 位置都用这户家庭到公路的起点的距离来计算,第i户家庭距起点的距 离为di.每年,蓝桥村都要举行一次集会.今年,由于村里的 ...
- 2016年第七届蓝桥杯C/C++程序设计本科B组省赛
/* 2016年第七届蓝桥杯C/C++程序设计本科B组省赛 煤球数目(结果填空) 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形) ...
- 2015年第六届蓝桥杯C/C++程序设计本科B组决赛
1.积分之谜(枚举) 2.完美正方形 3.关联账户(并查集) 4.密文搜索 5.居民集会 6.模型染色 1.积分之迷 小明开了个网上商店,卖风铃.共有3个品牌:A,B,C.为了促销,每件商品都会返固定 ...
- 2015年第六届蓝桥杯C/C++程序设计本科B组决赛 完美正方形
完美正方形 如果一些边长互不相同的正方形,可以恰好拼出一个更大的正方形,则称其为完美正方形.历史上,人们花了很久才找到了若干完美正方形.比如:如下边长的22个正方形 2 3 4 6 7 8 12 13 ...
- 2016年第六届蓝桥杯C/C++程序设计本科B组决赛 ——一步之遥(填空题题)
一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里.矿车停在平直的废弃的轨道上.他的面前是两个按钮,分别写着“F”和“B”. 小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退.按F,会 ...
- 第八届蓝桥杯C/C++程序设计本科B组决赛 ——发现环(编程大题_签到题_tarjan判环)
标题:发现环 小明的实验室有N台电脑,编号1~N.原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络.在树形网络上,任意两台电脑之间有唯一的路径相连. 不过在最近一次维护网络时,管理员误操 ...
随机推荐
- 最简单的策略模式代替if-else实战
一.需求 根据用户vip等级来返回不同的价格,vip等级是不固定的,随时可能要增加,价格也不是固定的. 二.常规的写法 /** * 如果有新增类型,就需要频繁的修改此处的代码! * 不符合开闭原则! ...
- mysql存储过程demo
#删除存储过程 -- drop procedure if exists add_test; CREATE PROCEDURE add_test() begin #定义变量 declare client ...
- 转:如何正确彻底删除webpack 全局或是局部?
原文链接:如何正确彻底删除webpack 全局或是局部? 就需要卸载cli 配置webpack ,提示需要安装 webpack-cli,选择yes 后安装webpack-cli , 可是问题不断,所以 ...
- 开始使用 Manjaro(添加源+字体渲染去模糊+软件安装+优化配置+常见错误)(30)
1. 添加 archlinux 镜像源 1. 步骤一 向 /etc/pacman.d/mirrorlist 中添加国内镜像地址 1.1 方法1:自动添加 1. 输入如下命令查看国内镜像源,并按质量排序 ...
- django使用pyecharts(5)----django加入echarts_增量更新_定长
五.Django 前后端分离_定时增量更新图表定长数据 1.安装 djangorestframework linux pip3 install djangorestframework windows ...
- Redis 的基本操作、Key的操作及命名规范
Redis基本操作 查看数据的状态 pong redis 给我们返回 PONG,表示 redis 服务 运行正常 redis 默认用 使用 16 个 库 • Redis 默认使用 16 个库,从 0 ...
- GitHub的Fork是什么意思
GitHub的Fork 是什么意思[转] GitHub Help Simple guide to forks in GitHub and Git GitHub的Fork 是什么意思-N神3-博客园 G ...
- mysql全面整理(用于复习、查阅)--正在更新
Mysql学习 1. 关键字与函数名称全部大写 2. 数据库名称.表名称.字段名称全部小写 3. SQL语句必须以分号结尾 一.数据库基本操作 1. 创建.查看数据库 CREATE {DATABASE ...
- NoSql 使用小结
NoSql 使用小结 足够的冗余 如果出现要拿某个 id 去查另外的 collection 的情况,说明应该往这个增加所要查询的字段 实在要做关联查询的话,是不是应该考虑关系型的数据库,关系和非关系混 ...
- RabbitMQ消息队列入门(一)——RabbitMQ消息队列的安装(Windows环境下)
一.RabbitMQ介绍1.RabbitMQ简介RabbitMQ是一个消息代理:它接受和转发消息.你可以把它想象成一个邮局:当你把你想要发布的邮件放在邮箱中时,你可以确定邮差先生最终将邮件发送给你的收 ...