搭积木小明最近喜欢搭数字积木,一共有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;
}