搭积木小明最近喜欢搭数字积木,一共有10块积木,每个积木上有一个数字,0~9。 搭积木规则:每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。最后搭成4层的金字塔形,必须用完所有的积木。 下面是两种合格的搭法:
0
1 2
3 4 5
6 7 8 9
0
3 1
7 5 2
9 8 6 4
请你计算这样的搭法一共有多少种? 请填表示总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int a[11];
bool vis[11]={false};
int countt=0;
void dfs(int step){
if(step==10){
if(a[0] < a[1] && a[0] < a[2]&& a[1] < a[3] && a[1] < a[4] && a[2] < a[4] && a[2] < a[5]&& a[3] < a[6] && a[3] < a[7] && a[4] < a[7] && a[4] < a[8] && a[5] < a[8] && a[5] < a[9]){
countt++;
}
return;
}
for(int i=0;i<10;i++){
if(vis[i]==false){
a[step]=i;
vis[i]=true;
dfs(step+1);
vis[i]=false;
}
}
}
int main(){
dfs(0);
cout<<countt<<endl;
}
振兴中华
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振
我做起振兴
做起振兴中
起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,
但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
答案是一个整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
//值为0表示"从",值为1表示"我",值为2表示"做",值为3表示"起",值为4表示"振",值为5表示"兴",值为6表示"中",值为7表示"华",
int map[4][5] = {
{0,1,2,3,4},
{1,2,3,4,5},
{2,3,4,5,6},
{3,4,5,6,7}
};
int cnt=0;
bool vis[6][6];
void dfs(int x,int y,int step){
if(map[x][y]==7&&step==7){
cnt++;
return;
}
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
for(int i=0;i<4;i++){
int dx=x+dir[i][0];
int dy=y+dir[i][1];
if(dx<0||dx>3||dy<0||dy>4){
continue;
}
if(vis[dx][dy]==false&&map[dx][dy]==map[x][y]+1){
vis[dx][dy]=1;
dfs(dx,dy,step+1);
vis[dx][dy]=0;
}
}
return;
}
int main(){
memset(vis,0,sizeof(vis));
dfs(0,0,0);
cout<<cnt<<endl;
}
填算式
请看下面的算式:
(ABCD - EFGH) * XY = 900
每个字母代表一个0~9的数字,不同字母代表不同数字,首位不能为0。
比如,(5012 - 4987) * 36 就是一个解。
请找到另一个解,并提交该解中 ABCD 所代表的整数。
请严格按照格式,通过浏览器提交答案。
注意:只提交 ABCD 所代表的整数,不要写其它附加内容,比如:说明性的文字。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int a[11];
bool vis[11]={false};
int cnt=0;
void dfs(int step){
if(step==10){
if(a[0]!=0&&a[4]!=0&&a[8]!=0&&( (a[0]*1000+a[1]*100+a[2]*10+a[3]) - (a[4]*1000+a[5]*100+a[6]*10+a[7]) ) * (a[8]*10+a[9]) == 900){
cnt++;
cout<<a[0]<<a[1]<<a[2]<<a[3]<<endl;
return;
}
}
for(int i=0;i<10;i++){
if(vis[i]==false){
a[step]=i;
vis[i]=1;
dfs(step+1);
vis[i]=0;
}
}
return ;
}
int main(){
dfs(0);
cout<<cnt<<endl;
return 0;
}
骰子迷题
小明参加了少年宫的一项趣味活动:每个小朋友发给一个空白的骰子
(它的6个面是空白的,没有数字),要小朋友自己设计每个面写哪个数字。
但有如下要求:
1. 每个面只能填写 0 至 8 中的某一个数字。
2. 不同面可以填写同样的数字,但6个面总和必须等于24。
填好后,小朋友可以用自己填写好数字的骰子向少年宫的两个机器人挑战
----玩掷骰子游戏。规则如下:
三方同时掷出自己的骰子,如果出现任何相同的数字,则三方都不计分。
如果三方数字都不同,则最小数字一方扣 1 分,最大数字一方加 1 分。
小明看到了两个机器人手中的骰子分别是:
0 0 0 8 8 8
1 1 4 5 6 7
请你替小明算一下,他如何填写,才能使自己得分的概率最大。
请提交小明应该填写的6个数字,按升序排列,数字间用一个空格分开。
如果认为有多个答案,提交字母序最小的那个方案。
请严格按照格式,通过浏览器提交答案。
注意:只提交一行内容,含有6个被空格分开的数字。不要写其它附加内容,
比如:说明性的文字。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int a[9];
int save[9];
int robot1[6]={0,0,0,8,8,8};
int robot2[6]={1,1,4,5,6,7};
int maxn=0;
void dfs(int step){
if(step==6){
int sum=0;
for(int i=0;i<6;i++)sum+=a[i];
if(sum==24){
int win=0;
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
for(int k=0;k<6;k++){
if(a[i]>robot1[j]&&a[i]>robot2[k]){
win++;
}
}
}
}
if(win>maxn){
maxn=win;
for(int i=0;i<6;i++){
save[i]=a[i];
}
}
}
return ;
}
for(int i=0;i<=8;i++){
a[step]=i;
dfs(step+1);
}
return ;
}
int main(){
dfs(0);
for(int i=0;i<6;i++)cout<<save[i]<<" ";
return 0;
}
寒假作业
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
【】+【】=【】
【】-【】=【】
【】*【】=【】
【】/【】=【】
每个方块代表1~13中的某一个数字,但不能重复。
比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int a[13];
bool vis[13]={0};
int cnt;
void dfs(int step){
if(step==3){
if((a[0]+a[1])!=a[2])return ;
}
if(step==6){
if((a[3]-a[4])!=a[5])return ;
}
if(step==9){
if((a[6]*a[7])!=a[8])return ;
}
if(step==12){
if((a[11]*a[10])==a[9]){
cnt++;
return ;
}
}
for(int i=1;i<=13;i++){
if(vis[i]==false){
a[step]=i;
vis[i]=1;
dfs(step+1);
vis[i]=0;
}
}
return ;
}
int main(){
dfs(0);
cout<<cnt<<endl;
return 0;
}
方格填数
如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include<iostream>
#include<cmath>
using namespace std;
double a[10];
bool visit[10];
int cnt=0;
void dfs(int step)
{
if(step==10)
{
if(abs(a[0]-a[4]) != 1.0 && abs(a[0]-a[1]) != 1.0 && abs(a[0]-a[3]) != 1.0 && abs(a[0]-a[5]) != 1.0
&& abs(a[1]-a[5]) != 1.0 && abs(a[1]-a[2]) != 1.0 && abs(a[1]-a[4]) != 1.0 && abs(a[1]-a[6]) != 1.0
&& abs(a[2]-a[6]) != 1.0 && abs(a[2]-a[5]) != 1.0
&& abs(a[3]-a[7]) != 1.0 && abs(a[3]-a[4]) != 1.0 && abs(a[3]-a[8]) != 1.0
&& abs(a[4]-a[8]) != 1.0 && abs(a[4]-a[9]) != 1.0 && abs(a[4]-a[7]) != 1.0
&& abs(a[5]-a[9]) != 1.0 && abs(a[5]-a[6]) != 1.0 && abs(a[5]-a[8]) != 1.0
&& abs(a[6]-a[9]) != 1.0){
cnt++;
}
return;
}
for(int i = 0;i < 10;i ++)
{
if(visit[i] == false)
{
a[step] = i;
visit[i] = true;
dfs(step+1);
visit[i] = false;
}
}
return;
}
int main()
{
dfs(0);
cout<<cnt<<endl;
return 0;
}
扑克序列
A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。
要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。
请填写出所有符合要求的排列中,字典序最小的那个。
例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。
请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。
字符间一定不要留空格。
新知识:
//在字符串中从下标位置为pos开始查找字符c,若找到则返回下标位置
int string::find(Char c, int pos)
//bool next_permutation(_BidirectionalIterator _first,_BidirectionalIterator _last)
next_permutation函数则是将按字母表顺序生成给定序列的下一个较大的排列,
直到整个序列为降序为止。
prev_permutation函数与之相反,是生成给定序列的上一个较小的排列。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
cout<<"符合要求的排列为:"<<endl;
string s = "223344AA";
do
{
unsigned iab = s.find("A", 0);
unsigned iae = s.find("A", iab + 1);
unsigned i2b = s.find("2", 0);
unsigned i2e = s.find("2", i2b + 1);
unsigned i3b = s.find("3", 0);
unsigned i3e = s.find("3", i3b + 1);
unsigned i4b = s.find("4", 0);
unsigned i4e = s.find("4", i4b + 1);
if(iae - iab == 2 && i2e - i2b == 3 && i3e - i3b == 4 && i4e - i4b == 5)
{
cout << s << endl;
}
} while(next_permutation(s.begin(), s.end()));
return 0;
}
猜年龄
美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。 他曾在1935~1936年应邀来中国清华大学讲学。
一次,他参加某个重要会议,年轻的脸孔引人注目。 于是有人询问他的年龄,他回答说:
“我年龄的立方是个4位数。我年龄的4次方是个6位数。 这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,他当时到底有多年轻。
通过浏览器,直接提交他那时的年龄数字。
注意:不要提交解答过程,或其它的说明文字。
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int book[13];
bool flag;
int main(){
int a=10;
for(;a<99;a++){
flag=true;
memset(book,0,sizeof(book));
int b=(int)pow(a,3);
int c=(int)pow(a,4);
if(b/1000==0||b/1000>=10)continue;
if(c/100000==0||c/100000>=10)continue;
// cout<<a<<" "<<b<<" "<<c<<endl;
do{
book[b%10]++;
b/=10;
}while(b);
do{
book[c%10]++;
c/=10;
}while(c);
for(int i=0;i<10;i++)
{
// cout<<book[i]<<" ";
if(book[i]==1){}
else{
flag=false;
break;
}
}
if(flag==true)cout<<a<<endl;
}
return 0;
}