当前位置:   article > 正文

第十四届蓝桥杯c/c++B组 赛后复盘wa_蓝桥杯考试要禁用cincout输出流吗

蓝桥杯考试要禁用cincout输出流吗

 复盘反思:

  今天打完蓝桥杯,感觉自己被雷到了,简单题做不出,复杂题也只会暴力。感觉两个月的备赛就是场笑话,全程没有优美的算法可言,只有一层层堆砌的暴力循环。经过这场比赛,我明白了自己极其不扎实的技术功底以及缺乏参加大赛的经历。我在备战蓝桥杯的前期是使用acwing的,天天手抄y总代码以为自己有多牛b,最后到头来样样学不精。今年的自己确实令我失望,不过咱也不能气馁。从哪里跌倒,就要从哪里爬起来。趁着现在才大一,好好的沉淀一年,不要追求快速!不要自以为是!不要浮躁。明年,我还来捐300.不过那时候,我一定会拿回属于我的荣誉!!!

题目复盘

 试题A:日期统计

 【考试状态】:

  看到第一题名字的时候还以为又是什么签到题,毕竟以往几年的蓝桥杯的日期题我从来没有卡过。可是因为第一次参加比赛,我紧张得不得了,题都没读明白,后来明白了题意,判断的时候又总是不能完全不重不漏,写了半个小时的各种循环判断,最后还是选择手算。提交的答案是327,错大离谱了。

【题意分析】:

  其实,题目的思想本身不难,但是模拟很是复杂。而且现在其实我还是没有搞懂条件1

和条件2不是有冲突吗?子序列要为8,可是条件2又变相的告诉我子序列不一定为8,遇到单日期只需要补上前导0就行??????我就是这里好迷糊。算了,继续来分析。我们可以分单月单日期、单月双日期、双月单日期、双月双日期四个方式来做到不重不漏。然后借助dfs的来找到我们的答案。

这是考试时我的思路

 利用dfs算法思想 (学长给的代码,还没吃透hh)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. set<string> st;
  5. int mon[13] = { 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  6. int a[110];
  7. //s是日期,id是100位数组编号,u是枚举到第几位,v是s的每一位
  8. void dfs(string s, int id, int u, char v)
  9. {
  10. if (u == 9) {
  11. st.insert(s);
  12. // cout << s << "\n";
  13. return;
  14. }
  15. if (id > 100) return;
  16. if (u == 1) {
  17. if (a[id] == 2) {
  18. dfs(s + '2', id + 1, u + 1, 2);
  19. }
  20. }
  21. else if (u == 2) {
  22. if (a[id] == 0) {
  23. dfs(s + '0', id + 1, u + 1, 0);
  24. }
  25. }
  26. else if (u == 3) {
  27. if (a[id] == 2) {
  28. dfs(s + '2', id + 1, u + 1, 2);
  29. }
  30. }
  31. else if (u == 4) {
  32. if (a[id] == 3) {
  33. dfs(s + '3', id + 1, u + 1, 3);
  34. }
  35. }
  36. else if (u == 5) {
  37. if (a[id] <= 1) {
  38. char c = '0' + a[id];
  39. dfs(s + c, id + 1, u + 1, a[id]);
  40. }
  41. }
  42. else if (u == 6) {
  43. if (v == 0 && a[id] == 0) {
  44. }
  45. else if (v == 0 && a[id] > 0) {
  46. char c = '0' + a[id];
  47. dfs(s + c, id + 1, u + 1, a[id]);
  48. }
  49. else if (v == 1 && a[id] <= 2) {
  50. char c = '0' + a[id];
  51. dfs(s + c, id + 1, u + 1, a[id]);
  52. }
  53. }
  54. else if (u == 7) {
  55. if (a[id] <= 3) {
  56. char c = '0' + a[id];
  57. dfs(s + c, id + 1, u + 1, a[id]);
  58. }
  59. }
  60. else if (u == 8) {
  61. if (v == 3) {
  62. int num = (s[4] - '0') * 10 + s[5] - '0';
  63. if (mon[num] == 31 && a[id] <= 1) {
  64. char c = '0' + a[id];
  65. dfs(s + c, id + 1, u + 1, a[id]);
  66. }
  67. }
  68. else if (v == 0 && a[id] == 0) {
  69. }
  70. else {
  71. char c = '0' + a[id];
  72. dfs(s + c, id + 1, u + 1, a[id]);
  73. }
  74. }
  75. char c = '0' + a[id];
  76. dfs(s, id + 1, u, v);
  77. }
  78. int main() {
  79. ios::sync_with_stdio(false);
  80. cin.tie(0);
  81. for (int i = 1; i <= 100; ++i) {
  82. cin >> a[i];
  83. }
  84. dfs("", 1, 1, 0);
  85. cout << st.size() << "\n";
  86. return 0;
  87. }

 【复盘代码】

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[100],ans;
  4. bool vis[20240000];
  5. bool check(int date){ //判断日期合法性
  6. if(vis[date]) return false;
  7. vis[date]=true;
  8. int mm=date/100%100;
  9. int dd=date%100;
  10. if(mm<1||mm>12)return false;
  11. if(mm==1||mm==3||mm==5||mm==7||mm==8||mm==10||mm==12){
  12. if(dd>=1&&dd<=31) return true;
  13. }else if(mm==2){
  14. if(dd>=1&&dd<=28)return true;
  15. }else if(dd>=1&&dd<=30)return true;
  16. else return false;
  17. }
  18. void dfs(int x,int pos,int date){ //x是当前枚举的下标,pos是当前枚举的位数,date是当前组成的日期
  19. if(x==100)return ;
  20. if(pos==8){
  21. if(check(date))++ans;
  22. return;
  23. }
  24. if((pos==0&&a[x]==2)|| //将每一位的合法情况进行判断
  25. (pos==1&&a[x]==0)||
  26. (pos==2&&a[x]==2)||
  27. (pos==3&&a[x]==3)||
  28. (pos==4&&a[x]>=0&&a[x]<=1)||
  29. (pos==5&&a[x]>=0&&a[x]<=9)||
  30. (pos==6&&a[x]>=0&&a[x]<=3)||
  31. (pos==7&&a[x]>=0&&a[x]<=9))
  32. dfs(x+1,pos+1,date*10+a[x]); //选择这个数
  33. dfs(x+1,pos,date); //不选这个数
  34. }
  35. int main()
  36. {
  37. ios::sync_with_stdio(0);cin.tie(0); //关闭流同步
  38. for(int i=0;i<100;i++)cin>>a[i];
  39. dfs(0,0,0);
  40. cout<<ans;
  41. return 0;
  42. }

 答案:235

试题B:01串的熵

【题意分析】

   学会加工题目信息。如果有i个0,那么则有n-i个1.而且0必定比1出现少。所以枚举一半即可。然后可以化成

 填空题枚举就行了!

【复盘代码】

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long double db;
  4. const db ans = 11625907.5798,eps=1e-4;
  5. const int N =23333333;
  6. int main()
  7. {
  8. for(int i=0;i<=N/2;i++) //0的个数
  9. {
  10. int u = N-i;
  11. db res=-1.0*u*u/N*log2(1.0*u/N)-1.0*i*i/N*log2(1.0*i/N);
  12. if(fabs(res-ans)<eps){
  13. cout<<i;
  14. return 0;
  15. }
  16. }
  17. return 0;
  18. }

答案:11027421

试题C:冶炼金属

【考试状态】

  这题可能是我最有把握的题目了,一拿到题目,我就想到了逆向分析。然后明确了一个思路。拿一个MAXN数组和一个MINN数组分别保存取下界的值(然后再数组里找一个最小值),MINN数组保存上界值(然后取数组的最大值)。也不知道对不对,只去过了样例。

【考试代码】

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. const int N = 10010;
  6. int MAXN[N], MINN[N];
  7. int n, k ;
  8. int main()
  9. {
  10. scanf("%d", &n);
  11. while (n--)
  12. {
  13. int a, b;
  14. scanf("%d%d", &a, &b);
  15. MAXN[k] = a / b;
  16. if ((a * 1.0 / (b + 1) > a / (b + 1)))MINN[k] = a / (b + 1) + 1;
  17. else MINN[k] = a / (b + 1);
  18. k++;
  19. }
  20. sort(MAXN, MAXN + k);
  21. sort(MINN, MINN + k);
  22. printf("%d %d", MINN[k - 1] ,MAXN[0]);
  23. return 0;
  24. }

【复盘代码】二分法:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAX_N=1e4+1;
  4. int N,A[MAX_N],B[MAX_N];
  5. bool check_min(int V)
  6. {
  7. for(int i=1;i<=N;i++)
  8. if(A[i]/V>B[i])return false;
  9. else return true;
  10. }
  11. bool check_max(int V)
  12. {
  13. for(int i=1;i<=N;i++)
  14. if(A[i]/V<B[i])return false;
  15. return true;
  16. }
  17. int main()
  18. {
  19. ios::sync_with_stdio(0);cin.tie(0);
  20. cin>>N;
  21. for(int i=1;i<=N;i++)cin>>A[i]>>B[i];
  22. //二分答案过程
  23. int L=1,R=1000000000,V_min;
  24. while(L<=R)
  25. {
  26. int mid = (L+R)>>1;
  27. if(check_min(mid)){
  28. V_min=mid;
  29. R=mid-1;
  30. }else L=mid+1;
  31. }
  32. L=1,R=1000000000;int V_max;
  33. while(L<=R)
  34. {
  35. int mid=L+R>>1;
  36. if(check_max(mid)){
  37. V_max=mid;
  38. L=mid+1;
  39. }else R=mid-1;
  40. }
  41. cout<<V_min<<' '<<V_max;
  42. return 0;
  43. }

试题D:飞机降落

 【题意分析】

  飞机降落问题,看到数据范围的时候,立马想到了贪心模型,想着用全排列的方式去做,数据规模大概在3*10^9,会超时,不过可以过大部分样例。思路是这样,但是考试真的不会写这种排列hh。现在我还记得考试前我复习到的一个全排列函数next_permutation。赛后听到大佬讲用dfs+剪枝的方法可以大大减小数据规模(如果前面某驾飞机已经判断不能降落了,那么就不用再向全排列一样继续枚举),然后跟着大佬去尝试写代码

【复盘代码】dfs+剪枝

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 11;
  4. int T[N],D[N],L[N];
  5. bool used[N],have_answer; //是否尝试降落,是否有答案
  6. int n;
  7. void dfs(int x,int tim){ //已经降落了几架,现在所用时间
  8. if(have_answer) return; //找到答案,就跳出
  9. if(x==n){ //如果降落n架,有解
  10. have_answer=1;
  11. return;
  12. }
  13. for(int i=1;i<n;i++)
  14. if(!used[i]&&tim<T[i]+D[i]){ //没降落,而且现在花费的时间小于这架飞机的最大停留时间
  15. used[i]=1; //成功降落
  16. dfs(x+1,max(T[i],tim)+L[i]); //最早在T【i】时间降落,这里取个max值
  17. if(have_answer)return; //找到答案,跳出
  18. used[i]=0; //否则回复原样
  19. }
  20. }
  21. void solve(){
  22. have_answer=0; //开头默认没有解
  23. cin>>n;
  24. for(int i=1;i<=N;i++){
  25. cin>>T[i]>>D[i]>>L[i];
  26. used[i]=0;
  27. }
  28. dfs(0,0);
  29. if(have_answer)cout<<"YES\n";
  30. else cout<<"NO\n";
  31. }
  32. int main()
  33. {
  34. ios::sync_with_stdio(0);cin.tie(0);
  35. int t;
  36. cin>>t;
  37. while(t--) solve();
  38. return 0;
  39. }

试题E:接龙数列

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/1005413
推荐阅读
相关标签
  

闽ICP备14008679号