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

来源:互联网 发布:php setcookie 作用域 编辑:程序博客网 时间:2024/04/28 09:13

<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;}/*100100=3+69258/714100=81+5643/297100=81+7524/396100=82+3546/197100=91+5742/638100=91+5823/647100=91+7524/836100=94+1578/263100=96+1428/357100=96+1752/438100=96+2148/537一共有:11种情况运行时间:8.41s105105=72+6534/198105=87+3456/192105=87+9612/534105=92+5681/437105=92+6734/518105=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;}/*53 4 2 5 19*/