• 蓝桥杯历届试题题解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;
    }
    


  • 相关阅读:
    centos svn的配置使用
    bind 的使用
    我 && yii2 (二)
    我 && yii2 (一)
    vue handsontable 插件 如何验证该行内的某项内容是否填写 !
    sass穿透 scoped 的情况下 去修改ui组件的样式
    vue 3.0 编译巨慢 结局方法
    element-ui tree树形节点 自定义图标
    element
    treeselect 表单验证解决方法
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7010973.html
Copyright © 2020-2023  润新知