蓝桥杯历届试题题解1

4月11日省赛,给自己加油!


矩阵翻硬币:给定n,m。这么大的数据非常明显找规律。。。。打表处理小数据,代码:

int a[500][500];
int main(){
	int n,m,ans;
	int i,j,k,l;
	while(scanf("%d%d",&n,&m)!=EOF){
		memset(a,0,sizeof(a));
		ans=0;
		for(i=1;i<=n;i++)
			for(j=1;j<=m;j++)
				for(k=1;k<=n;k++)
					for(l=1;l<=m;l++)
						if (k%i==0&&l%j==0)
							a[k][l]^=1;
		for(i=1;i<=n;i++){
			for(j=1;j<=m;j++){
				if (a[i][j]) ans++;
				printf("%d ",a[i][j]);
			}
			puts("");
		}
		printf("%d

",ans);
	}
	return 0;
}

发现仅仅有平方数的地方不一样。。那么如果n中有a个平方数,m中有b个,答案就是a*b。

直接上大数模版就可以!

或者用Java。

。。


兰顿蚂蚁:模拟。看懂题目跟着做就好了。注意,题中已经规定好坐标从(0,0)開始算,对有Pascal习惯的童鞋。。。

看清楚题目!

实现的小技巧:依照顺序(逆时针或者顺时针的方向)排列上下左右,在处理转弯的时候特别方便。

上代码:

int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
//方向为上,右,下,左

int map[200][200];

int main(){
	int i,j;
	char s[5];
	scanf("%d%d",&m,&n);
	for(i=0;i<m;i++)
		for(j=0;j<n;j++)
			scanf("%d",&map[i][j]);
	scanf("%d%d%s%d",&x,&y,s,&k);
	int dir;
        if (s[0]=='U') dir=0;//初始的方向定好
	else if (s[0]=='D') dir=2;
	else if (s[0]=='L') dir=3;
	else dir=1;
	while(k--){
		if (map[x][y]){//右转
			map[x][y]=1-map[x][y];
			dir=(dir+1)%4;
			x+=dx[dir];
			y+=dy[dir];
		}
		else{//白格。左转90 
			map[x][y]=1-map[x][y];
			dir=(dir-1+4)%4;
			x+=dx[dir];
			y+=dy[dir];
		}
	}
	printf("%d %d
",x,y);
	return 0;
}

分糖果:模拟啊。。。不知道多少次,那么推断一次假设不满足条件继续运行就好了

int a[maxn],b[maxn];
int ans,n;

void solve(){
	int i;
	for(i=0;i<n;i++){
		b[(i+n-1)%n]=a[i]/2;
		a[i]/=2;
	}
	for(i=0;i<n;i++){
		a[i]+=b[i];
		b[i]=0;
		if (a[i]%2){
			a[i]++;
			ans++;
		}
	}
}

int main(){
	int i,j,k;
	while(scanf("%d",&n)!=EOF){
		for(i=0;i<n;i++) scanf("%d",&a[i]);
		ans=0;
		while(1){
			int flag=0;
			for(i=1;i<n;i++)
				if (a[i]!=a[0]){
					flag=1;
					break;
				}
			if (flag) solve();
			else break;
		}
		printf("%d
",ans);
	}
	return 0;
}

数字游戏:模拟题。注意数学符号%的使用。不须要真正依照循环报数去找。每次间隔的数有规律的,找到规律直接输出

num是每次报的数。看着式子肯定能够找到规律(从等差来想)

long long n,m,t,add,first,final,i,j,k,num,ans;
int main(){
	//freopen("input.txt","r",stdin);
	scanf("%I64d%I64d%I64d",&n,&k,&t);
	ans=num=1;
	for(i=0;i<t-1;i++){
		first=i*n+1;
		final=i*n+n;
		add=(first+final)*n/2;
		add=add%k;
		num=(num+add)%k;
		ans+=num;
	}
	printf("%I64d
",ans);
}

回文数字:暴力算呗

const int maxn=1000050;

int ans[maxn],tot=0;
int main(){
	int i,j,k,n;
	scanf("%d",&n);
	for(i=1;i<=9;i++)
		for(j=0;j<=9;j++)
			for(k=0;k<=9;k++){
				if (2*i+2*j+k==n) ans[++tot]=i+j*10+k*100+j*1000+i*10000;
				if (2*i+2*j+2*k==n) ans[++tot]=i+j*10+k*100+k*1000+j*10000+i*100000;
			}
	sort(ans+1,ans+1+tot);
	for(i=1;i<=tot;i++)
		printf("%d
",ans[i]);
	if (tot==0) puts("-1");
	return 0;
}

买不到的数目:这道题是个数论结论题:答案为n*m-n-m

能够证明从n*m-n-m+1到无穷大的整数都能够用a*n+b*m表示


或者不知道结论就打表啊!!

什么时候能够表示的数连续了,找到那个连续的数開始的位置,-1,就是答案。

n和m都不大,是能够试试的。


连号区间数:不知道跟并查集有半毛钱关系。。。

或者是我笨。

。。

还是找的数学规律

int main(){
	scanf("%d",&n);
	for(i=1;i<=n;i++) scanf("%d",&num[i]);
	for(i=1;i<=n;i++){
		int minnum=num[i];
		int maxnum=num[i];
		for(j=i;j<=n;j++){
			minnum=min(num[j],minnum);
			maxnum=max(num[j],maxnum);
			if (maxnum-minnum==j-i) ans++;
                        //假设满足这个条件说明!

!  } } printf("%d ",ans); return 0; }


翻硬币:认为算不上。贪心。就是从左到右循环一次来更改一次,直到目标状态

const int maxn=2000;
char s1[maxn],s2[maxn];
int a[maxn],b[maxn],ans;

int main(){
	//freopen("input.txt","r",stdin);
	scanf("%s%s",s1,s2);
	ans=0;
	int len=strlen(s1),i,j,k;
	for(i=0;i<len;i++){
		if (s1[i]=='o') a[i]=0;
		else a[i]=1;
		if (s2[i]=='o') b[i]=0;
		else b[i]=1;
	}
	for(i=0;i<len;i++){
		if (a[i]!=b[i]){
			ans++;
			a[i]=1-a[i];
			a[i+1]=1-a[i+1];
		}
	}
	printf("%d
",ans);
	return 0;
}

错误票据:这样的题用map做好了啊,基础map使用。注意:假设反复的和连续的出如今一起啦。。细节条件推断

const int maxn=500;
int a[maxn];
map<int,int>mp;
int ans1,ans2,n,num,i,j,k,tot;

int main(){
	//freopen("input.txt","r",stdin);
	scanf("%d",&n);
	mp.clear();
	tot=0;
	while(scanf("%d",&num)!=EOF){
		 a[tot++]=num;
		 mp[a[tot-1]]++;
	}
	sort(a,a+tot);
	for(i=0;i<tot;i++)
		if (mp[a[i]]==2){
			ans2=a[i];
			break;
		}
	for(i=0;i<tot;i++)
		if (a[i]+1!=a[i+1]&&mp[a[i]]==1){
			ans1=a[i]+1;
			break;
		}
	printf("%d %d
",ans1,ans2);
	return 0;
}

带分数:最最自豪的一道题,感觉自己的代码无敌!

首先。此题肯定是个暴力题,怎么暴力。。

。是个问题

N=A+B*C。表示成这样假设直接模拟算A。B,C。然后判重。然后判等,当然能够做,只是依照ACM的想法,考虑最大数据1000000不可能1s出解

注意,1-9的全排列能够全然表示出A。B和C

所以仅仅须要表示出A,B和C。


Step1:生成1到9的全排列

Step2:将全排列的数组生成A和B和C

Step3:判等


代码例如以下:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;

#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 99999999
#define pi 3.1415926535897932384626433832795028841971

int num[10],vis[10],n,ans=0;

void check(){
	int i,j,a,b,c,num1,num2,num3;
	for(i=1;i<=9;i++)
		for(j=i+1;j<=9;j++){
			num1=num2=num3=0;
			for(a=1;a<=i;a++) num1=num1*10+num[a];
			for(b=i+1;b<j;b++) num2=num2*10+num[b];
			for(c=j;c<=9;c++) num3=num3*10+num[c];
			
			if (num1+num2/num3==n&&num2%num3==0){
				ans++;
				//printf("%d %d %d
",num1,num2,num3);
			}
		}
}

void dfs(int p){
	if (p==10){
		//for(int i=1;i<=9;i++) printf("%d%c",num[i],i==9?'
':' ');
		check();
		return;
	}
	for(int i=1;i<=9;i++)
		if (!vis[i]){
			vis[i]=1;
			num[p]=i;
			dfs(p+1);
			vis[i]=0;
		}
	return;
}
int main(){
	int i,j,k;
	scanf("%d",&n);
	memset(vis,0,sizeof(vis));
	dfs(1);
	printf("%d
",ans);
	return 0;
}

由此方法。能够进一步得出打表的代码,例如以下:

注意推断范围在1000000以内!

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;

#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 99999999
#define pi 3.1415926535897932384626433832795028841971

int num[10],vis[10],n;
int ans[1000050];

void check(){
	int i,j,a,b,c,num1,num2,num3;
	for(i=1;i<=9;i++)
		for(j=i+1;j<=9;j++){
			num1=num2=num3=0;
			for(a=1;a<=i;a++) num1=num1*10+num[a];
			for(b=i+1;b<=j-1;b++) num2=num2*10+num[b];
			for(c=j;c<=9;c++) num3=num3*10+num[c];
			
			if (num2%num3==0&&num1+num2/num3<=1000000) ans[num1+num2/num3]++;
		}
}

void dfs(int p){
	if (p==10){
		//for(int i=1;i<=9;i++) printf("%d%c",num[i],i==9?'
':' ');
		check();
		return;
	}
	for(int i=1;i<=9;i++)
		if (!vis[i]){
			vis[i]=1;
			num[p]=i;
			dfs(p+1);
			vis[i]=0;
		}
	return;
}
int main(){
	freopen("output.txt","w",stdout);
	int i,j,k;
	memset(vis,0,sizeof(vis));
	memset(ans,0,sizeof(ans));
	dfs(1);
	for(i=1;i<=1000000;i++){
		printf("%d,",ans[i]);
		if (i%80==0) puts("");
	}
	//fclose(stdout);
	//scanf("%d",&n);
	//printf("%d
",ans[n]);
	return 0;
}


原文地址:https://www.cnblogs.com/yxysuanfa/p/7010973.html