第七届蓝桥杯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条数据链接相连,恰好构成一个树形网络.在树形网络上,任意两台电脑之间有唯一的路径相连. 不过在最近一次维护网络时,管理员误操 ...
随机推荐
- Selenium2+python自动化2.7-火狐44版本环境搭建(转)
转载地址:https://www.cnblogs.com/yoyoketang/p/selenium.html 前言 目前selenium版本已经升级到3.0了,网上的大部分教程是基于2.0写的,所以 ...
- C# .NET 杀进程
procName 是进程名,不带.exe . private bool IsAppKill(String procName) { try { ; System.Diagnostics.Process[ ...
- 安装Vim插件——ViPlugin
打开Eclipse,找到Help——Install New Software Name输入 viPlugin ,Location输入 viplugin.com ,点击OK 之后同意协议,然后等待下载 ...
- 你应该知道的4个DSP开发支持库
引言 在dsp开发中,为了节省开发时间和难度,TI将一些成熟的算法封装为模块,供开发者使用.如果能充分利用这些算法支持库,对于加快dsp开发进程与提高代码质量.稳定性有非常大的帮助. Digital ...
- Git常用命令及方法
https://blog.csdn.net/web_csdn_share/article/details/79243308 Git常用命令及方法大全 下面是我整理的常用 Git 命令清单.几个专用名词 ...
- Django 操作已经存在的数据库
反向操作数据库 何为反向操作.即是数据库在项目之前已经存在,不需要新建表,操作已经存在的表 # 进入站点目录下执行 python manage.py inspectdb #可以看到settings中连 ...
- java微服务的统一配置中心
为了更好的管理应用的配置,也为了不用每次更改配置都重启应用,我们可以使用配置中心 关于eureka的服务注册和rabbitMQ的安装使用(自动更新配置需要用到rabbitMQ)这里不赘述,只关注配置中 ...
- WUSTOJ 1311: 开心的金明(Java)动态规划-01背包
题目链接:
- PAT甲级题分类汇编——树
本文为PAT甲级分类汇编系列文章. AVL树好难!(其实还好啦~) 我本来想着今天应该做不完树了,没想到电脑里有一份讲义,PPT和源代码都有,就一遍复习一遍抄码了一遍,更没想到的是编译一遍通过,再没想 ...
- yum更换源配置
今天安装mysql5.7的时候出现了点问题,最后更换yum源解决了,把这个记录一下 yum源配置(阿里云源) 1) 安装wget yum install -y wget 2) 备份/etc/yum.r ...