第四届蓝桥杯C++本科B组预赛解题报告

<1> 高斯日记 
1799-7-16

package JiaNan;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class GaoSiRiJi
{
    static  Calendar c = new GregorianCalendar(1791,12-1,15);
	public static void main(String args[])
	{
		c.add(Calendar.DATE,8113-5343);
		System.out.println(c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)+"-"+c.get(Calendar.DATE));
	}
} 

/*
1799-7-16      //注意:Java中月份是从0开始的,因此虽然输出是1799-6-16,但是要写成1799-7-16
*/

<2>马虎的算式
142

方法1:高层循环,穷举法

package JiaNan;
public class MaHuDeSuanShi
{
    static int kinds = 0;
    static void f()
    {
    	for(int a = 1; a <= 9;a++)
    		for(int b = 1; b <= 9;b++)
    			for(int c = 1; c <= 9;c++)
    				for(int d = 1; d <= 9;d++)
    					for(int e = 1; e <= 9;e++)
    					{
    						int ab = 10*a + b;
    						int cde = 100*c + 10*d + e;
    						int adb = 100*a + 10*d + b;
    						int ce = 10*c + e;
    						if(ab*cde != adb*ce)
    							continue;
    						
    						int num[] = new int[10]; 
    						num[a]++;
    						num[b]++;
    						num[c]++;
    						num[d]++;
    						num[e]++;
    						int i;
    						for(i = 1;i <= 9;i++)
    						{
    							if(num[i] > 1)
    								break;
    						}
    						
    						if(i == 10)
  						    {
    					       //System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
  							   kinds++;
  						    }
    					}
    }
	public static void main(String args[])
	{
		long start = System.nanoTime();
		f();
		System.out.println(kinds);
		long end = System.nanoTime();
		System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
	}
} 

/*
142
运行时间:0.010208086s
*/


方法2:运用排列,进行穷举法

package JiaNan;
public class MaHuDeSuanShi
{
    static int kinds = 0;
    static int c[] = new int[6];         //枚举排列
    static boolean vis[] = new boolean[10];  //记录是否被访问
    static void check(int c[])
    {
		int ab = c[1]*10 + c[2];
		int cde = c[3]*100 + c[4]*10 + c[5];
		int adb = c[1]*100 + c[4]*10 + c[2];
		int ce = c[3]*10 + c[5];
		if(ab*cde == adb*ce)
		{
			//System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
			kinds++;
		}
    }
    static void dfs(int start,int n)
    {
		if(start == 6)
		{
			check(c);
			return;
		}
    	for(int i = 1;i <= n;i++)
		{
		   if(!vis[i])
		   {
			  c[start] = i;
			  vis[i] = true;
			  dfs(start+1,n);
			  vis[i] = false;
			   c[start] = 0;
		   }
		}
	}
	public static void main(String args[])
	{
		long start = System.nanoTime();
		dfs(1,9);
		System.out.println(kinds);
		long end = System.nanoTime();
		System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");	
	}
} 

/*
142
运行时间:0.002564503s
*/
//备注:由此可见,排列是一种比较高效率的算法,大约效率是循环穷举的5倍。由此想到21位水仙花也是利用排列做的,效率都非常高

<3>39台阶
51167078

#include<iostream>
using namespace std;
int num = 0;         //记录上台阶的方法总数
int  c[40];          //上台阶过程记录
void dfs(int start,int n)
{
	if(n <= 0)
	{
		if(n==0 && start%2==0)
		{
			num++;
		}
		return;
	}
	else
	{
		for(int i = 0;i <= 1;i++)
		{
			if(i == 0)
			{
				c[start] = 1;
				dfs(start+1,n-1);
			}
			else
			{  
				c[start] = 2;
				dfs(start+1,n-2);  
			}
		}
	}
	
}

void main()
{
	dfs(0,39);
	cout<<num<<endl;
}

/*
51167078
*/

<4>黄金连分数

0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497050372347293136948算法思想:在用递归f(n) = 1/(1+f(n-1));求解的过程中一直精确到300位,在最后输出时,再四舍五入到100位,这样将精度损失避免到最小

package JiaNan;
import java.math.BigDecimal;
import java.math.MathContext;
public class HuangJinLianFenShu
{
    static BigDecimal f(int n)
    {
		if(n == 1)
			return BigDecimal.valueOf(1.0);
		return BigDecimal.valueOf(1.0).divide(new BigDecimal(BigDecimal.valueOf(1.0).add(f(n-1)).toString()),new MathContext(300)); 
    }
	public static void main(String args[])
	{
		long start = System.nanoTime();
		BigDecimal des = new BigDecimal(f(200).toString(),new MathContext(100));
		System.out.println(des);
		long end = System.nanoTime();
		System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s"); 
	}
}
/*
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497050372347293136948
运行时间:0.08024721s
*/ 

<5>前缀判断
*haystack++ != *needle++

#include<iostream>
using namespace std;
char* prefix(char* haystack_start, char* needle_start)
{ 
	char* haystack = haystack_start; 
	char* needle = needle_start; 
	while(*haystack && *needle)
	{
		if(*haystack++ != *needle++) 
			return NULL; //填空位置 
	} 
	if(*needle) 
		return NULL;
	return haystack_start; 
}

void main()
{
	cout<<prefix("abc123","abc")<<endl;
}
/*
abc123
*/ 

<6>三部排序
p++

#include<iostream>
using namespace std;
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++; //填空位置 
		} 
	} 
}

void main()
{
	int x[] = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
	sort3p(x,sizeof(x)/sizeof(x[0]));
	for(int i = 0;i < sizeof(x)/sizeof(x[0]);i++)
		cout<<x[i]<<" ";
	cout<<endl;
}
/*
-3 -2 -16 -5 0 0 0 21 19 33 25 16 18 25
*/

<7>错误票据

#include<iostream>
#include<vector>
using namespace std;
void f(int N)
{
    if(N == 0)
		return;
	vector<int> v;
	int row = 0;
	while(1)
	{
		int num;
		cin>>num;
		v.push_back(num);
		if(cin.get() == '\n')
		{
			if(++row == N)
				break;
		}
	}
	
	int min = v[0],max = v[0];
	for(int i = 1;i <= v.size()-1;i++)
	{
		if(v[i] < min)
			min = v[i];
		if(v[i] > max)
			max = v[i];
	}
	
	int* len = new int[max];
	for(int m = 0;m < max;m++)
	{
		len[m] = 0;
	}
	
	for(int j = 0;j <= v.size()-1;j++)
	{
		len[v[j]]++;
	}
	
	for(int k = min;k <= max;k++)
	{
		if(len[k] == 0)
			cout<<k<<" ";
		if(len[k] > 1)
			cout<<k<<" ";
	}
}

void main()
{
	int N;
	cin>>N;
	f(N);
	cout<<endl;
}

<8>翻硬币

#include<iostream>
using namespace std;
int f(char sorc[],char dest[])
{
	int minTimes = 0;   //最少翻转次数
	char* p = sorc;
	char* q = dest;
	while(*p=='o' || *p=='*')
	{
		if(*p != *q)
		{
			switch(*p)
			{
			case '*':
				*p = 'o';
				if(*(p+1) == '*')
				{
					*(p+1) = 'o';
				}
				else
				{
					if(*(p+1) == 'o')
						*(p+1) = '*';
				}
				p++;
				q++;
				minTimes++;
				break;
			case 'o':
				*p = '*';
				if(*(p+1) == '*')
				{
					*(p+1) = 'o';
				}
				else
				{
					if(*(p+1) == 'o')
						*(p+1) = '*';
				}
				p++;
				q++;
				minTimes++;
				break;
			}
		}
		else             //设计程序,当你考虑到相等的情况,就要考虑到不等的情况
		{
			p++;
			q++;
		}
	}
	return minTimes;
}


void main()
{
	char sroc[30];
	char dest[30];
	cin>>sroc>>dest;
	cout<<f(sroc,dest)<<endl;
}

/*
**********
o****o****
5
*/

<9>带分数

#include<iostream>
#include<ctime>
using namespace std;
int N;
int c[10];      //记录1-9数字的全排列
bool vis[10];   //记录空间节点是否被访问过
int kinds = 0;
//
int GetWeiShu(int N)     //得到一个指定数字的位数
{
	int weishu = 0;
	while(N > 0)
	{
		weishu++;
		N /= 10;
	}
	return weishu;
}

/
int GetNum(int start,int end)
{
	int sum = 0;
	for(int i = start;i <= end;i++)
	{
		sum = sum*10 + c[i];
	}
	return sum;
}

/
void check(int N,int* c)
{
	for(int i = 1;i <= GetWeiShu(N);i++)
	{
		int midMinLen = (9-i+1)/2;
		for(int j = i+midMinLen;j <= 8;j++)
		{
			int X = GetNum(1,i);
			int Y = GetNum(i+1,j);
			int Z = GetNum(j+1,9);
			if(Y%Z==0 && N==X+Y/Z)
			{
				//cout<<N<<"="<<X<<"+"<<Y<<"/"<<Z<<endl;
				kinds++;
			}
		}
	}
	
}

/
void dfs(int start,int n)
{
	if(start == 10)
	{
		check(N,c);
		return;
	}
	
	for(int i = 1;i <= n;i++)
	{
		if(!vis[i])
		{
			c[start] = i;
			vis[i] = true;
			dfs(start+1,n);
			vis[i] = false;
		}
	}
}


void main()
{
	double start = clock();
	cin>>N;
	dfs(1,9);
	double end = clock();
	cout<<"一共有:"<<kinds<<"种情况"<<endl;
	cout<<"运行时间:"<<(end-start)/CLOCKS_PER_SEC<<"s"<<endl;	
}

/*
100
100=3+69258/714
100=81+5643/297
100=81+7524/396
100=82+3546/197
100=91+5742/638
100=91+5823/647
100=91+7524/836
100=94+1578/263
100=96+1428/357
100=96+1752/438
100=96+2148/537
一共有:11种情况
运行时间:8.41s

105
105=72+6534/198
105=87+3456/192
105=87+9612/534
105=92+5681/437
105=92+6734/518
105=98+3647/521
一共有:6种情况
运行时间:3.512s
*/

<10>连号区间数

#include<iostream>
#include<vector>
using namespace std;

vector<int> v;
int kinds = 0;

//
int GetMin(const vector<int> & v,int start,int end)
{
	int min = v[start];
	for(int i = start;i <= end;i++)
	{
		if(v[i] < min)
			min = v[i];
	}
	return min;
}

//
int GetMax(const vector<int> & v,int start,int end)
{
	int max = v[start];
	for(int i = start;i <= end;i++)
	{
		if(v[i] > max)
			max = v[i];
	}
	return max;
}

//
void f(const vector<int> & v)
{
	for(int i = 0;i < v.size();i++)
		for(int j = 0;j < v.size();j++)
		{
			int min = GetMin(v,i,j);
			int max = GetMax(v,i,j);
			if(j-i+1 == max-min+1)
			{
				kinds++;
			}
		}
}

void main()
{
	
	int N;
	cin>>N;
	while(N--)
	{
		int num;
		cin>>num;
		v.push_back(num);
	}
	f(v);
	cout<<kinds<<endl;
}

/*
5
3 4 2 5 1
9
*/ 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值