运行时间排列第四届蓝桥杯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

package JiaNan;
public class _39TaiJie
{
    static int kinds = 0;
    static int c[] = new int[40];   //最多走39步
    static int choice[] = new int[]{1,2};
    static void dfs(int start,int n)
    {
    	if(n <= 0)
    	{
    		if(n==0 && start%2==0)
    		{
    			kinds++;
    		}
    		return;
    	}
    	for(int i = 0;i <= 1;i++)
    	{
    		c[start] = choice[i];
    		dfs(start+1,n-choice[i]);        //对比上一题,总结何时须要恢复:当要避免重复时就须要vis数组记载一下避免重复,还有韩信走马分酒问题也是用了vis
    	}
    }
	public static void main(String args[])
	{
		long start = System.nanoTime();
		dfs(0,39);
		System.out.println(kinds);	
		long end = System.nanoTime();
		System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");	
	}
} 

/*
51167078
运行时间:5.390165205s
*/

    
<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 c[10];      //记载1-9数字的全排列
bool vis[10];   //记载空间节点是不是被拜访过

/////////////////
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* c)
{
   for(int i = 1;i <= 2;i++)
   {
	   int midMinLen = (9-i+1)/2;
	   for(int j = 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 && 100==X+Y/Z)
		   {
			   cout<<"100"<<"="<<X<<"+"<<Y<<"/"<<Z<<endl;
		   }
	   }
   }

}

/////////////////
void dfs(int start,int n)
{
	if(start == 10)
	{
		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;
		}
	}
}



void main()
{
	double start = clock();;
	dfs(1,9);
	double end = clock();
	cout<<"运行时间:"<<(end-start)/CLOCKS_PER_SEC<<"s"<<endl;
}

/*
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
运行时间:0.592s
*/

    
<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
*/

 

文章结束给大家分享下程序员的一些笑话语录: 爱情观
  爱情就是死循环,一旦执行就陷进去了。
  爱上一个人,就是内存泄露--你永远释放不了。
  真正爱上一个人的时候,那就是常量限定,永远不会改变。
  女朋友就是私有变量,只有我这个类才能调用。
  情人就是指针用的时候一定要注意,要不然就带来巨大的灾难。

posted @ 2013-05-19 19:45  xinyuyuanm  阅读(314)  评论(0编辑  收藏  举报