蓝桥杯\2016-省赛-C语言大学A组 题解

网友年龄

#include<sstream>
#include<string>
#include<iostream>
using namespace std;
int main(){
	for(char i ='0';i<='9';i++){
		for(char j ='1';j<='9';j++){
			stringstream a;
			a<<i<<j;
			int s;
			a>>s;
			a.clear();
			a.str("");
			a<<j<<i;
			int f;
			a>>f;
			if(f>s&&f-s==27)cout<<f<<endl;;
		}
	}
}

30
41
52
63
74
85
96

7组

生日蜡烛

#include<iostream>
using namespace std;
const int M = 236;
int main(){
	for(int i= 0;i<500;i++){
		int ans=0;
		for(int j = i ;;j++){
			ans+=j;
			if(ans==M)cout<<i<<endl;
			if(ans>M)break;
		}
	}
}

26
236

26

方格填数

#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<set>
#include<utility>
using namespace std;
const int empty=11;
const int invalid = 12;
const int D=8;
typedef pair<int ,int > dir;
int used[20];
int x[10];
const int I = 5;
const int J = 6;
int m[I][J] = {
	12,12,12,12,12,12,
	12,12,11,11,11,12,//(1,2)to (1,4)
	12,11,11,11,11,12,//(2,1)to (2,4)
	12,11,11,11,12,12,//(3,1)to (3,3)
	12,12,12,12,12,12
};
void load(){
	int i = 1;
	int cnt = 0 ;
	for(int j = 2;j<=4;j++){
		m[i][j]=x[cnt++];
	}
	i++;
	for(int j=1;j<=4;j++){
		m[i][j]=x[cnt++];
	}
	i++;
	for(int j = 1 ;j<=3;j++){
		m[i][j]=x[cnt++];
	}
}
dir dirs[10];
int tolcnt=0;
const int T=0;
#define IF if(T) 
void pA(){
	if(T)for(int i =0;i<I;i++){
		for(int j =0 ;j<J;j++){
			printf("%3d",m[i][j]);
		}
		printf("\n");
	}
}
int tolused[10];
bool dfs(){
	int i = 1,j=1;
	while(i<=3&&j<=4){
		memset(used,0,sizeof(used));
		for(int c=0;c<D;c++){
			int x=i+dirs[c].first;
			int y=j+dirs[c].second;
			int val = m[x][y];//这里写的不够骚,如果数相邻那么只要求abs(相邻值-中心值)!=1即可。这时empty和invalid要隔开一点起码2。
			used[val]++;
		}
		int val = m[i][j];
		IF {
			printf("in %d,%d\n",i,j);
			int ans=0;
			for(int i = 0 ;i< 20;i++){
				printf("%3d:%d",i,used[i]); 
				ans +=used[i];
			}
			printf("ans:%d & val :%d\n",ans,val );
		}
		if(val!=empty&&val!=invalid){
			if(val==0){if(used[1])return 0;

			}
			else if(val==9){if(used[8])return 0;

			}
			else if(used[val-1]||used[val+1])return 0;
		}
		j++;
		if(j==5){
			i++;
			j=1;
		}
		if(i==4)break;
	}
	return 1;
}
void init(){
	int cnt=0;
	for(int i = 0 ;i< 10;i++){
		x[i]=i;
	}
	for(int i = -1;i< 2;i++){
		for(int j =-1;j< 2;j++){
			if(!i&&!j)continue;
			dirs[cnt++]=make_pair(i,j);
		}
	}
}
int main(){
	init();
	int cnt = 0 ;
	do{
		cnt++;
//		if(cnt>2)exit(0);
		load();
		IF printf("%d\n", tolcnt);
		IF pA();
		if(dfs()){
			tolcnt++;
		}
		IF printf("-----");
	}while(next_permutation(x,x+10));
	printf("%d\n", tolcnt);
}

1580

写了挺久的,感觉要先从缩小规模,例如4×4,然后写得扩展性足够好,这样应该方便debug。
之前写了一个dfs,但写的dfs已经超过30层了,比较难debug。想要公用used数组,却没有还原,而且还memset它,memset还写错了,可以写成局部的。。建议写成宏。
阶乘
10! = 3 628 800 //3百万,十是可以的
11! = 39 916 800 //4千万
12! = 479 001 600 //4亿
13! = 6 227 020 800 //6十亿

#define MS(x) memset(x,0,sizeof(x))

快速排序

swap(a,p,j);

记得是有这个步骤的,但是具体的标号不记得,第三个参数是瞎试出来的。

消除尾一

去尾零,想复杂了

x=x&(x+1)

另外树状数组low_bit(x):return x&-x

寒假作业

仔细读题!从13个数选12个数填12个空!
人算反而比电脑快的例子。。
乘法、除法和加法、减法对称。
由于乘法少,先考虑乘法
|2×3=6|3×4=12|
|2×4=8||
|2×5=10||
|2×6=12||
需要乘法各一组,且用的数字没冲突,发现有且只有一组:
2×5=10,3×4=12
由对称性:2(乘法除法)×2(乘法交换)×2(除法交换)=8可能性
从剩下的(1,6,7,8,9,11,13)考虑加法:
|1+6=7|6+7=13|
|1+8=9||
同理发现有且仅有一组:
1+8=9、6+7=13
同样也是8种可能性
故答案是8×8=64

posted @ 2017-04-04 19:57  xsthunder  阅读(1071)  评论(0编辑  收藏  举报