蓝桥杯第四届省赛C/C++B组个人题解

版权声明:转载请注明出处https://blog.csdn.net/hhmy77 https://blog.csdn.net/hhmy77/article/details/88778368

39级台阶

在这里插入图片描述
经典的dp题目,因为是填空题我们直接搜吧 答案 51167078

#include<bits/stdc++.h>
using namespace std;
int num=0;
void DFS(int dep,int time)
{
	if(dep>39) return;
	if(dep==39)
	{
		if(time%2==0)
		{
			num++;
			return;
		}
		return;
	}
	DFS(dep+1,time+1);
	DFS(dep+2,time+1);
}
int main()
{
	DFS(0,0);
	cout<<num;
}

错误票据

A组中分析过了 https://blog.csdn.net/hhmy77/article/details/88777814

带分数

在这里插入图片描述
可以搜 也可以全排列,搜索比较暴力,全排列有技巧
全排列:
题目公式 N=L+U/D,求L,U,D

  1. 先排数字 得到一串长度为9的数字 它的形式是LUD
  2. 我们可以用(N-L)*D的最后一位%10得到U的最后一位
  3. 从头开始搜U,算U的最后一位,再判断UD即可
    这个算法会比全排列快很多很多…
#include<bits/stdc++.h>
using namespace std;
int ary[9]={1,2,3,4,5,6,7,8,9};
int N;
int ans=0;
int getNum(int s,int e)
{
	int temp=0;
	for(int i=s;i<=e;i++)temp=temp*10+ary[i];	
	return temp;
}
void check(int len)
{
	//确认L 
	for(int i=0;i<len;i++)
	{
		int L=0,U=0,D=0;
		L=getNum(0,i);
		//精妙之处 通过D的最后一位确定B的最后一位
		//然后查找B,得出C 接着判断即可 
		int bl=((N-L)*ary[8])%10;
		for(int j=4;j<9;j++)
		{
			if(ary[j]==bl)
			{
				U=getNum(i+1,j);
				D=getNum(j+1,8);
				if(U==(N-L)*D)
				{
					ans++;
					break;	
				}
			}
		}
	}
	
}
int main()
{
	cin>>N;
	int t=N;
	int len=0;
	while(t)len++,t/=10;
	do
	{
		check(len);
	}while(next_permutation(ary,ary+9));
	cout<<ans;
} 

搜索:

#include<bits/stdc++.h>
using namespace std;
bool check(int L,int U,int D)
{
	int flag[10]={0};
	while(L)
	{
		flag[L%10]++;
		if(flag[L%10]>1)return false;
		L/=10;
	}
	while(U)
	{
		flag[U%10]++;
		if(flag[U%10]>1)return false;
		U/=10;
	}
	while(D)
	{
		flag[D%10]++;
		if(flag[D%10]>1)return false;
		D/=10;
	}
	if(flag[0]!=0)return false;
	for(int i=1;i<10;i++)
	{
		if(flag[i]!=1)return false;
	}
	return true;
	
	
}
int main()
{
	int N;
	cin>>N;
	int ans=0;
	for(int L=1;L<N;L++)
	{
		for(int D=1;D<N+1000;D++)
		{
			int U=(N-L)*D;
			if(check(L,U,D))
			{
				ans++;
				printf("%d+%d/%d\n",L,U,D);
			}		
	}
	}
	cout<<ans;
} 

翻硬币

直接贪心,白给
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string str1,str2;
	cin>>str1>>str2;
	int f1[str1.size()],f2[str2.size()];
	for(int i=0;i<str1.size();i++)
	{
		if(str1[i]=='*')f1[i]=1;
		else f1[i]=-1;	
		if(str2[i]=='*')f2[i]=1;
		else f2[i]=-1;
//		if(str1[i]!=str2[i])
	}
	int num=0;
	for(int i=0;i<str1.size();i++)
	{
		if(f1[i]!=f2[i])
		{
			num++;
			f1[i]=-f1[i];
			f1[i+1]=-f1[i+1];
		}
	}
	cout<<num;
}

高斯日记

A组写过了 答案:1799-07-16

黄金连分数

在这里插入图片描述
斐波那契数列变形
1 1/2 2/3 3/5…
这道题由于精度的问题大家答案都不太一样
我的答案:0.618033988749894848204586834365638933292787846773161128182460911288271727817207568734093651288600386
做法
1.推出斐波那契数列
2.模拟除法 先x/y得到一位 x=(x%y)*10 即x/y
可惜我笔记本没带,不然我一定贴上模拟除法的过程
如https://www.cnblogs.com/wkfvawl/p/9484044.html 这篇文章所述

  1. 526.32/23 = 22
  2. 新的被除数 为526.32%23*10=200
  3. 依次类推
    在这里插入图片描述
#include<bits/stdc++.h>
using namespace std;

int main()
{
	long long int fb[100]={1,1};
	for(int i=2;i<100;i++)
	{
		fb[i]=fb[i-1]+fb[i-2];
	}
//	cout<<fb[79]<<" "<<fb[49]<<endl;
	long long int x=fb[78];
	long long int y=fb[79];
	int time=0;
	int ary[102];
	while(time!=100)
	{
		ary[time++]=x/y;
		x=(x%y)*10;
	}
	for(int i=0;i<100;i++)cout<<ary[i];
	 
} 

连号区间数

比较简单 直接上代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n=0;
	cin>>n;
	vector<int>vt;
	for(int i=0;i<n;i++)
	{
		int a;
		cin>>a;
		vt.push_back(a);
	}
	//遍历取区间 查看是否连续  set去重 
	int num=0;
	for(int i=0;i<vt.size();i++)
	{
		for(int j=i+1;j<vt.size();j++)
		{
			vector<int>tempt;
			set<int>st;
			for(int k=i;k<=j;k++)
			{
				tempt.push_back(vt[k]);
				st.insert(vt[k]);
			}
			sort(tempt.begin(),tempt.end());
			int flag=1;
			for(int n=tempt[0];n<=tempt[tempt.size()-1];n++)
			{
				if(st.count(n)==0) 
				{
					flag=0;
					break;	
				}
			}
			if(flag)num++;
			else break;
		}
	}
	cout<<num+vt.size();
}

马虎的算式

这道题直接暴力就好了

#include<bits/stdc++.h>
using namespace std;
void clear(int flag[])
{
	for(int i=0;i<11;i++)flag[i]=0;
}
bool check(int flag[],int num)
{
	if(flag[num]==1)return false;
	return true;
}
int main()
{
	int ans=0;
	int flag[11];
	clear(flag);
	for(int i1=1;i1<10;i1++)
	{
		int ary[6]={0};
		ary[1]=i1;
		for(int i2=1;i2<10;i2++)
		{
			//如果可以加 
			ary[2]=i2;
			for(int i3=1;i3<10;i3++)
			{
				ary[3]=i3;
				for(int i4=1;i4<10;i4++)
				{
					ary[4]=i4;
					for(int i5=1;i5<10;i5++)
					{
						ary[5]=i5;
						int flag[11]={0};
						bool ok=true;
						for(int i=1;i<6;i++)
						{
							if(flag[ary[i]]==1)
							{
								ok=false;
								break;
							}else flag[ary[i]]=1;
						}
						if(!ok)continue;
						int A=((ary[1]*10+ary[2])*(ary[3]*100+ary[4]*10+ary[5]));
						int B=((ary[3]*10+ary[5])*(ary[1]*100+ary[4]*10+ary[2]));
						if(A==B)ans++;
						
					}
				}
			}
		}
		clear(flag);
	}
	cout<<ans;
}

前缀

A组做过了

三部排序

这个思想大家可以了解下 挺不错

void sort3p(int* x, int len)
{
	int p = 0;
	int left = 0;
	int right = len-1;
	
	while(p<=right){
		if(x[p]<0){
			int t = x[left];
			x[left] = x[p];
			x[p] = t;
			left++;
			p++;
		}
		else if(x[p]>0){
			int t = x[right];
			x[right] = x[p];
			x[p] = t;
			right--;			
		}
		else{
			p++; 
//			__________________________;  //填空位置
		}
	}
}

猜你喜欢

转载自blog.csdn.net/hhmy77/article/details/88778368