第四届蓝桥杯C++本科B组预赛解题报告-转自themagickeyjianan的专栏

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

分类: 蓝桥杯 294人阅读 评论(0) 收藏 举报

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

  1. package JiaNan;
  2. import java.util.Calendar;
  3. import java.util.GregorianCalendar;
  4. public class GaoSiRiJi
  5. {
  6. static Calendar c = new GregorianCalendar(1791,12-1,15);
  7. public static void main(String args[])
  8. {
  9. c.add(Calendar.DATE,8113-5343);
  10. System.out.println(c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)+"-"+c.get(Calendar.DATE));
  11. }
  12. }
  13. /*
  14. 1799-7-16 //注意:Java中月份是从0开始的,因此虽然输出是1799-6-16,但是要写成1799-7-16
  15. */

<2>马虎的算式
142

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

  1. package JiaNan;
  2. public class MaHuDeSuanShi
  3. {
  4. static int kinds = 0;
  5. static void f()
  6. {
  7. for(int a = 1; a <= 9;a++)
  8. for(int b = 1; b <= 9;b++)
  9. for(int c = 1; c <= 9;c++)
  10. for(int d = 1; d <= 9;d++)
  11. for(int e = 1; e <= 9;e++)
  12. {
  13. int ab = 10*a + b;
  14. int cde = 100*c + 10*d + e;
  15. int adb = 100*a + 10*d + b;
  16. int ce = 10*c + e;
  17. if(ab*cde != adb*ce)
  18. continue;
  19. int num[] = new int[10];
  20. num[a]++;
  21. num[b]++;
  22. num[c]++;
  23. num[d]++;
  24. num[e]++;
  25. int i;
  26. for(i = 1;i <= 9;i++)
  27. {
  28. if(num[i] > 1)
  29. break;
  30. }
  31. if(i == 10)
  32. {
  33. //System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
  34. kinds++;
  35. }
  36. }
  37. }
  38. public static void main(String args[])
  39. {
  40. long start = System.nanoTime();
  41. f();
  42. System.out.println(kinds);
  43. long end = System.nanoTime();
  44. System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
  45. }
  46. }
  47. /*
  48. 142
  49. 运行时间:0.010208086s
  50. */


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

  1. package JiaNan;
  2. public class MaHuDeSuanShi
  3. {
  4. static int kinds = 0;
  5. static int c[] = new int[6]; //枚举排列
  6. static boolean vis[] = new boolean[10]; //记录是否被访问
  7. static void check(int c[])
  8. {
  9. int ab = c[1]*10 + c[2];
  10. int cde = c[3]*100 + c[4]*10 + c[5];
  11. int adb = c[1]*100 + c[4]*10 + c[2];
  12. int ce = c[3]*10 + c[5];
  13. if(ab*cde == adb*ce)
  14. {
  15. //System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
  16. kinds++;
  17. }
  18. }
  19. static void dfs(int start,int n)
  20. {
  21. if(start == 6)
  22. {
  23. check(c);
  24. return;
  25. }
  26. for(int i = 1;i <= n;i++)
  27. {
  28. if(!vis[i])
  29. {
  30. c[start] = i;
  31. vis[i] = true;
  32. dfs(start+1,n);
  33. vis[i] = false;
  34. c[start] = 0;
  35. }
  36. }
  37. }
  38. public static void main(String args[])
  39. {
  40. long start = System.nanoTime();
  41. dfs(1,9);
  42. System.out.println(kinds);
  43. long end = System.nanoTime();
  44. System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
  45. }
  46. }
  47. /*
  48. 142
  49. 运行时间:0.002564503s
  50. */
  51. //备注:由此可见,排列是一种比较高效率的算法,大约效率是循环穷举的5倍。由此想到21位水仙花也是利用排列做的,效率都非常高

<3>39台阶
51167078

  1. package JiaNan;
  2. public class _39TaiJie
  3. {
  4. static int kinds = 0;
  5. static int c[] = new int[40]; //最多走39步
  6. static int choice[] = new int[]{1,2};
  7. static void dfs(int start,int n)
  8. {
  9. if(n <= 0)
  10. {
  11. if(n==0 && start%2==0)
  12. {
  13. kinds++;
  14. }
  15. return;
  16. }
  17. for(int i = 0;i <= 1;i++)
  18. {
  19. c[start] = choice[i];
  20. dfs(start+1,n-choice[i]); //对比上一题,总结何时需要恢复:当要避免重复时就需要vis数组记录一下避免重复,还有韩信走马分酒问题也是用了vis
  21. }
  22. }
  23. public static void main(String args[])
  24. {
  25. long start = System.nanoTime();
  26. dfs(0,39);
  27. System.out.println(kinds);
  28. long end = System.nanoTime();
  29. System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
  30. }
  31. }
  32. /*
  33. 51167078
  34. 运行时间:5.390165205s
  35. */


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

  1. package JiaNan;
  2. import java.math.BigDecimal;
  3. import java.math.MathContext;
  4. public class HuangJinLianFenShu
  5. {
  6. static BigDecimal f(int n)
  7. {
  8. if(n == 1)
  9. return BigDecimal.valueOf(1.0);
  10. return BigDecimal.valueOf(1.0).divide(new BigDecimal(BigDecimal.valueOf(1.0).add(f(n-1)).toString()),new MathContext(300));
  11. }
  12. public static void main(String args[])
  13. {
  14. long start = System.nanoTime();
  15. BigDecimal des = new BigDecimal(f(200).toString(),new MathContext(100));
  16. System.out.println(des);
  17. long end = System.nanoTime();
  18. System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
  19. }
  20. }
  21. /*
  22. 0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497050372347293136948
  23. 运行时间:0.08024721s
  24. */

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

  1. #include<iostream>
  2. using namespace std;
  3. char* prefix(char* haystack_start, char* needle_start)
  4. {
  5. char* haystack = haystack_start;
  6. char* needle = needle_start;
  7. while(*haystack && *needle)
  8. {
  9. if(*haystack++ != *needle++)
  10. return NULL; //填空位置
  11. }
  12. if(*needle)
  13. return NULL;
  14. return haystack_start;
  15. }
  16. void main()
  17. {
  18. cout<<prefix("abc123","abc")<<endl;
  19. }
  20. /*
  21. abc123
  22. */

<6>三部排序
p++

  1. #include<iostream>
  2. using namespace std;
  3. void sort3p(int* x, int len)
  4. {
  5. int p = 0;
  6. int left = 0;
  7. int right = len-1;
  8. while(p<=right)
  9. {
  10. if(x[p]<0)
  11. {
  12. int t = x[left];
  13. x[left] = x[p];
  14. x[p] = t;
  15. left++;
  16. p++;
  17. }
  18. else if(x[p]>0)
  19. {
  20. int t = x[right];
  21. x[right] = x[p];
  22. x[p] = t;
  23. right--;
  24. }
  25. else
  26. {
  27. p++; //填空位置
  28. }
  29. }
  30. }
  31. void main()
  32. {
  33. int x[] = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
  34. sort3p(x,sizeof(x)/sizeof(x[0]));
  35. for(int i = 0;i < sizeof(x)/sizeof(x[0]);i++)
  36. cout<<x[i]<<" ";
  37. cout<<endl;
  38. }
  39. /*
  40. -3 -2 -16 -5 0 0 0 21 19 33 25 16 18 25
  41. */


<7>错误票据

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. void f(int N)
  5. {
  6. if(N == 0)
  7. return;
  8. vector<int> v;
  9. int row = 0;
  10. while(1)
  11. {
  12. int num;
  13. cin>>num;
  14. v.push_back(num);
  15. if(cin.get() == '\n')
  16. {
  17. if(++row == N)
  18. break;
  19. }
  20. }
  21. int min = v[0],max = v[0];
  22. for(int i = 1;i <= v.size()-1;i++)
  23. {
  24. if(v[i] < min)
  25. min = v[i];
  26. if(v[i] > max)
  27. max = v[i];
  28. }
  29. int* len = new int[max];
  30. for(int m = 0;m < max;m++)
  31. {
  32. len[m] = 0;
  33. }
  34. for(int j = 0;j <= v.size()-1;j++)
  35. {
  36. len[v[j]]++;
  37. }
  38. for(int k = min;k <= max;k++)
  39. {
  40. if(len[k] == 0)
  41. cout<<k<<" ";
  42. if(len[k] > 1)
  43. cout<<k<<" ";
  44. }
  45. }
  46. void main()
  47. {
  48. int N;
  49. cin>>N;
  50. f(N);
  51. cout<<endl;
  52. }


<8>翻硬币

  1. #include<iostream>
  2. using namespace std;
  3. int f(char sorc[],char dest[])
  4. {
  5. int minTimes = 0; //最少翻转次数
  6. char* p = sorc;
  7. char* q = dest;
  8. while(*p=='o' || *p=='*')
  9. {
  10. if(*p != *q)
  11. {
  12. switch(*p)
  13. {
  14. case '*':
  15. *p = 'o';
  16. if(*(p+1) == '*')
  17. {
  18. *(p+1) = 'o';
  19. }
  20. else
  21. {
  22. if(*(p+1) == 'o')
  23. *(p+1) = '*';
  24. }
  25. p++;
  26. q++;
  27. minTimes++;
  28. break;
  29. case 'o':
  30. *p = '*';
  31. if(*(p+1) == '*')
  32. {
  33. *(p+1) = 'o';
  34. }
  35. else
  36. {
  37. if(*(p+1) == 'o')
  38. *(p+1) = '*';
  39. }
  40. p++;
  41. q++;
  42. minTimes++;
  43. break;
  44. }
  45. }
  46. else //设计程序,当你考虑到相等的情况,就要考虑到不等的情况
  47. {
  48. p++;
  49. q++;
  50. }
  51. }
  52. return minTimes;
  53. }
  54. void main()
  55. {
  56. char sroc[30];
  57. char dest[30];
  58. cin>>sroc>>dest;
  59. cout<<f(sroc,dest)<<endl;
  60. }
  61. /*
  62. **********
  63. o****o****
  64. 5
  65. */


<9>带分数

  1. #include<iostream>
  2. #include<ctime>
  3. using namespace std;
  4. int N;
  5. int c[10]; //记录1-9数字的全排列
  6. bool vis[10]; //记录空间节点是否被访问过
  7. int kinds = 0;
  8. //////////////////
  9. int GetWeiShu(int N) //得到一个指定数字的位数
  10. {
  11. int weishu = 0;
  12. while(N > 0)
  13. {
  14. weishu++;
  15. N /= 10;
  16. }
  17. return weishu;
  18. }
  19. /////////////////
  20. int GetNum(int start,int end)
  21. {
  22. int sum = 0;
  23. for(int i = start;i <= end;i++)
  24. {
  25. sum = sum*10 + c[i];
  26. }
  27. return sum;
  28. }
  29. /////////////////
  30. void check(int N,int* c)
  31. {
  32. for(int i = 1;i <= GetWeiShu(N);i++)
  33. {
  34. int midMinLen = (9-i+1)/2;
  35. for(int j = i+midMinLen;j <= 8;j++)
  36. {
  37. int X = GetNum(1,i);
  38. int Y = GetNum(i+1,j);
  39. int Z = GetNum(j+1,9);
  40. if(Y%Z==0 && N==X+Y/Z)
  41. {
  42. //cout<<N<<"="<<X<<"+"<<Y<<"/"<<Z<<endl;
  43. kinds++;
  44. }
  45. }
  46. }
  47. }
  48. /////////////////
  49. void dfs(int start,int n)
  50. {
  51. if(start == 10)
  52. {
  53. check(N,c);
  54. return;
  55. }
  56. for(int i = 1;i <= n;i++)
  57. {
  58. if(!vis[i])
  59. {
  60. c[start] = i;
  61. vis[i] = true;
  62. dfs(start+1,n);
  63. vis[i] = false;
  64. }
  65. }
  66. }
  67. void main()
  68. {
  69. double start = clock();
  70. cin>>N;
  71. dfs(1,9);
  72. double end = clock();
  73. cout<<"一共有:"<<kinds<<"种情况"<<endl;
  74. cout<<"运行时间:"<<(end-start)/CLOCKS_PER_SEC<<"s"<<endl;
  75. }
  76. /*
  77. 100
  78. 100=3+69258/714
  79. 100=81+5643/297
  80. 100=81+7524/396
  81. 100=82+3546/197
  82. 100=91+5742/638
  83. 100=91+5823/647
  84. 100=91+7524/836
  85. 100=94+1578/263
  86. 100=96+1428/357
  87. 100=96+1752/438
  88. 100=96+2148/537
  89. 一共有:11种情况
  90. 运行时间:8.41s
  91. 105
  92. 105=72+6534/198
  93. 105=87+3456/192
  94. 105=87+9612/534
  95. 105=92+5681/437
  96. 105=92+6734/518
  97. 105=98+3647/521
  98. 一共有:6种情况
  99. 运行时间:3.512s
  100. */


<10>连号区间数

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. vector<int> v;
  5. int kinds = 0;
  6. //////////////////
  7. int GetMin(const vector<int> & v,int start,int end)
  8. {
  9. int min = v[start];
  10. for(int i = start;i <= end;i++)
  11. {
  12. if(v[i] < min)
  13. min = v[i];
  14. }
  15. return min;
  16. }
  17. //////////////////
  18. int GetMax(const vector<int> & v,int start,int end)
  19. {
  20. int max = v[start];
  21. for(int i = start;i <= end;i++)
  22. {
  23. if(v[i] > max)
  24. max = v[i];
  25. }
  26. return max;
  27. }
  28. //////////////////
  29. void f(const vector<int> & v)
  30. {
  31. for(int i = 0;i < v.size();i++)
  32. for(int j = 0;j < v.size();j++)
  33. {
  34. int min = GetMin(v,i,j);
  35. int max = GetMax(v,i,j);
  36. if(j-i+1 == max-min+1)
  37. {
  38. kinds++;
  39. }
  40. }
  41. }
  42. void main()
  43. {
  44. int N;
  45. cin>>N;
  46. while(N--)
  47. {
  48. int num;
  49. cin>>num;
  50. v.push_back(num);
  51. }
  52. f(v);
  53. cout<<kinds<<endl;
  54. }
  55. /*
  56. 5
  57. 3 4 2 5 1
  58. 9
  59. */
posted @ 2013-05-27 19:54  YuntaoWu  阅读(181)  评论(0编辑  收藏  举报