蓝桥杯 2016 C++ A 题解

部分题 所有题见链接

链接:https://pan.baidu.com/s/1gqmAgmnPQcZ48U5zjrGyUg
提取码:jpoz

T3 方格填数

如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+

(如果显示有问题,也可以参看【图1.jpg】)

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm> 
#include <cstring>
using namespace std ;

int ans = 0;

int  check(int a[]){
	if(a[0]-a[4]==-1||a[0]-a[4]==1)
		return 0;
	if(a[3]-a[4]==-1||a[3]-a[4]==1)
		return 0;
	if(a[5]-a[4]==-1||a[5]-a[4]==1)
		return 0;
	if(a[7]-a[4]==-1||a[7]-a[4]==1)
		return 0;
	if(a[8]-a[4]==-1||a[8]-a[4]==1)
		return 0;
	if(a[9]-a[4]==-1||a[9]-a[4]==1)
		return 0;
	if(a[1]-a[4]==-1||a[1]-a[4]==1)
		return 0;
	if(a[1]-a[5]==-1||a[1]-a[5]==1)
		return 0;
	if(a[1]-a[6]==-1||a[1]-a[6]==1)
		return 0;
	if(a[0]-a[5]==-1||a[0]-a[5]==1)
		return 0;
	if(a[2]-a[5]==-1||a[2]-a[5]==1)
		return 0;
	if(a[8]-a[5]==-1||a[8]-a[5]==1)
		return 0;
	if(a[9]-a[5]==-1||a[9]-a[5]==1)
		return 0;
	if(a[6]-a[5]==-1||a[6]-a[5]==1)
		return 0;
	if(a[6]-a[9]==-1||a[6]-a[9]==1)
		return 0;
	if(a[6]-a[2]==-1||a[6]-a[2]==1)
		return 0;
	if(a[3]-a[0]==-1||a[3]-a[0]==1)
		return 0;
	if(a[3]-a[7]==-1||a[3]-a[7]==1)
		return 0;
	if(a[8]-a[7]==-1||a[8]-a[7]==1)
		return 0;
	if(a[8]-a[3]==-1||a[8]-a[3]==1)
		return 0;
	if(a[9]-a[8]==-1||a[9]-a[8]==1)
		return 0;
	if(a[1]-a[0]==-1||a[1]-a[0]==1)
		return 0;
	if(a[1]-a[2]==-1||a[1]-a[2]==1)
		return 0;
}



//手动全排列 
void f(int k ,int a[]){
	//出口
	if(k == 10){
		if(check(a)!= 0 ){
			ans++;
		}
		return ;
	} 
	for(int i = k; i<10 ; ++i){
		{int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;}  //深入 
		f(k+1,a);
		{int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //回溯 
	}
	
	
}


void i2s(int x, string &basic_string) {
    stringstream ss;
    ss << x;
    ss >> basic_string;
}

void s2i(string &basic_string , int &x ) {
    stringstream ss;
    ss << basic_string;
    ss >> x;
}

void c2i(char &basic_string , int &x ) {
    stringstream ss;
    ss << basic_string;
    ss >> x;
}




void c2s(char c , string & s){
	stringstream stream;
	stream << c;
	s = stream.str();
}


//自动全排列 
void f1(string s, int a[]){
	
	do{
		for(int i=0 ; i<10 ; ++i){
			int temp  ;
		//	string temps ;
		//	c2s (s[i],temps);
		//	s2i(temps,temp);
			c2i(s[i],temp);
			a[i] = temp ;
		}
		
		check(a);
		
	}while(next_permutation(s.begin(),s.end()));
	
} 


int main(){
	//int a[10]={0,1,2,3,4,5,6,7,8,9};
	//f(0,a);
	int a[10];
	string  s ="0123456789" ;
	f1(s,a);
	
	
	cout<<ans<<endl;
}

  T6 寒假作业

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □

(如果显示不出来,可以参见【图1.jpg】)


每个方块代表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 <string>
#include <sstream>
#include <algorithm> 
#include <math.h>
using namespace std ;

int ans = 0;


int  check(int a[]){
	bool b1 = (a[0]+a[1])==a[2] ;
	bool b2 = (a[3]-a[4])==a[5] ;
	bool b3 = (a[6]*a[7])==a[8] ;
	bool b4=(fabs((a[9]*1.0)/(a[10]*1.0)-a[11]*1.0)<=0.00000000000001);
	if(b1&&b2&&b3&&b4)return 1;
	
	
	return 0;
}


//手动全排列 
void f(int k ,int a[]){
	//出口
	if(k==4){
		if(a[0]+a[1] != a[2])return ;
	}
	if(k==7){
		if(a[3]-a[4] != a[5])return ;
	}
	if(k==10){
		if(a[6]*a[7] != a[8])return ;
	}
	
	if(k == 13){
		if(check(a)==1){
			ans++;
			for(int i = 0; i<13 ; ++i){
				cout<<a[i];
			}cout<<endl;
		}
		return ;
	} 
	for(int i = k; i<13 ; ++i){
		{int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;}  //深入 
		f(k+1,a);
		{int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //回溯 
	}
	
	
}

int main (){
	int a[13]={1,2,3,4,5,6,7,8,9,10,11,12,13};
	f(0,a);
	cout<<ans<<endl;   //64
} 

  T7  剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)


比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

 

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm> 
#include <math.h>
using namespace std ;

int ans = 0;

int check1(int a[],int i){
	switch (i){
		case 0: if(a[1]>0 || a[4]>0)return 1;
		case 1: if(a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1;
		case 2 : if(a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1;
		case 3: if(a[2]>0 || a[7]>0)return 1;
		case 4: if(a[0]>0 || a[5>0] || a[8]>0)return 1;
		case 5: if(a[i-4]>0 || a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1;
		case 6: if(a[i-4]>0 || a[i-1]>0 || a[i+1]>0 || a[i+4]>0)return 1;
		case 7: if(a[3]>0 || a[6]>0 || a[11]>0)return 1;
		case 8: if(a[4]>0 || a[9]>0 )return 1;
		case 9: if(a[i-1]>0 || a[i+1]>0 || a[i-4]>0)return 1;
		case 10: if(a[i-1]>0 || a[i+1]>0 || a[i-4]>0)return 1;
		case 11: if(a[7]>0 || a[10]>0 )return 1;
		default: return 0;
	}
}

int  check(int a[]){
	for(int i =0; i<12 ; ++i ){
		if(a[i]==1){
			if(check1(a,i)!=1) return 0;
		}
	}
	return 1;
}

void c2i(char &basic_string , int &x ) {
    stringstream ss;
    ss << basic_string;
    ss >> x;
}


//自动全排列 
void f1(string s, int a[]){
	
	do{
		for(int i=0 ; i<12 ; ++i){
			int temp  ;
			c2i(s[i],temp);
			a[i] = temp ;
		}
		
		if(check(a)==1){
			ans++;
			for(int i = 0; i<12 ; ++i){
				cout<<a[i];
			}cout<<endl;
		}
		
		
	}while(next_permutation(s.begin(),s.end()));
	
} 


//手动全排列 
void f(int k ,int a[]){
	//出口
	if(k == 12){
		if(check(a)==1){
			ans++;
			for(int i = 0; i<12 ; ++i){
				cout<<a[i];
			}cout<<endl;
		}
		return ;
	} 
	for(int i = k; i<12 ; ++i){
		{int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;}  //深入 
		f(k+1,a);
		{int temp = a[k] ; a[k] = a[i] ; a[i] = temp ;} //回溯 
	}
}

int main (){
	//int a[12]={1,2,3,4,5,-1,-2,-3,-4,-5,-6,-7};
	string s = "123400000005" ;
	int a[12];
	f1(s,a);
	cout<<ans<<endl; 
} 

  T8 四平方和

四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。

比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)

对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法


程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开

例如,输入:
5
则程序应该输出:
0 0 1 2

再例如,输入:
12
则程序应该输出:
0 2 2 2

再例如,输入:
773535
则程序应该输出:
1 1 267 838

资源约定:
峰值内存消耗 < 256M
CPU消耗 < 3000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

#include <iostream>
#include <math.h>
#include <map> 
#include <cmath>
#include <time.h>
#include <stdio.h> 

using namespace std;

map<int , int> cache;

void f1(int n){
	for(int c = 0 ; c*c<n/10 ;++c){
		for(int d = c ; c*c+d*d<=n ; ++d )
		{
			if(cache.find(c*c+d*d)==cache.end()) cache[c*c+d*d]=c;
		}
	}
}


//a b找 
void f2(int n){
	for(int a =0;a*a<n/8;++a){
		for(int b=a;a*a+b*b <n/4 ;++b){
			if(cache.find(n-a*a-b*b)!=cache.end()){
				//找到了符合的c d
				int c = cache[n-a*a-b*b] ;
				int d = sqrt(n-a*a-b*b-c*c);
				printf("%d %d %d %d
",a,b,c,d);
				return ;
			}
		}
	}
}


int main(){
	long int n;
	cin>>n;
	

	 // 使用clock()构造clock_t对象(实际上是long类型的变量)
    clock_t t1 = clock();
	
	//缓存 
	f1(n);
	//找 
	f2(n);
	
	
	// 计算clock差,除以clock数/每秒,即可求出秒数
    // 将秒数乘以1000得到毫秒数
    cout << (clock() - t1) * 1.0 / CLOCKS_PER_SEC * 1000 << endl;
	
	return 0 ;
} 

  

原文地址:https://www.cnblogs.com/Stephen-Jixing/p/12627838.html