赞
踩
今天打完蓝桥杯,感觉自己被雷到了,简单题做不出,复杂题也只会暴力。感觉两个月的备赛就是场笑话,全程没有优美的算法可言,只有一层层堆砌的暴力循环。经过这场比赛,我明白了自己极其不扎实的技术功底以及缺乏参加大赛的经历。我在备战蓝桥杯的前期是使用acwing的,天天手抄y总代码以为自己有多牛b,最后到头来样样学不精。今年的自己确实令我失望,不过咱也不能气馁。从哪里跌倒,就要从哪里爬起来。趁着现在才大一,好好的沉淀一年,不要追求快速!不要自以为是!不要浮躁。明年,我还来捐300.不过那时候,我一定会拿回属于我的荣誉!!!
看到第一题名字的时候还以为又是什么签到题,毕竟以往几年的蓝桥杯的日期题我从来没有卡过。可是因为第一次参加比赛,我紧张得不得了,题都没读明白,后来明白了题意,判断的时候又总是不能完全不重不漏,写了半个小时的各种循环判断,最后还是选择手算。提交的答案是327,错大离谱了。
其实,题目的思想本身不难,但是模拟很是复杂。而且现在其实我还是没有搞懂条件1
和条件2不是有冲突吗?子序列要为8,可是条件2又变相的告诉我子序列不一定为8,遇到单日期只需要补上前导0就行??????我就是这里好迷糊。算了,继续来分析。我们可以分单月单日期、单月双日期、双月单日期、双月双日期四个方式来做到不重不漏。然后借助dfs的来找到我们的答案。
这是考试时我的思路
利用dfs算法思想 (学长给的代码,还没吃透hh)
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- set<string> st;
- int mon[13] = { 31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
- int a[110];
-
-
- //s是日期,id是100位数组编号,u是枚举到第几位,v是s的每一位
- void dfs(string s, int id, int u, char v)
- {
- if (u == 9) {
- st.insert(s);
- // cout << s << "\n";
- return;
- }
- if (id > 100) return;
- if (u == 1) {
- if (a[id] == 2) {
- dfs(s + '2', id + 1, u + 1, 2);
- }
- }
- else if (u == 2) {
- if (a[id] == 0) {
- dfs(s + '0', id + 1, u + 1, 0);
- }
- }
- else if (u == 3) {
- if (a[id] == 2) {
- dfs(s + '2', id + 1, u + 1, 2);
- }
- }
- else if (u == 4) {
- if (a[id] == 3) {
- dfs(s + '3', id + 1, u + 1, 3);
- }
- }
- else if (u == 5) {
- if (a[id] <= 1) {
- char c = '0' + a[id];
- dfs(s + c, id + 1, u + 1, a[id]);
- }
- }
- else if (u == 6) {
- if (v == 0 && a[id] == 0) {
-
- }
- else if (v == 0 && a[id] > 0) {
- char c = '0' + a[id];
- dfs(s + c, id + 1, u + 1, a[id]);
- }
- else if (v == 1 && a[id] <= 2) {
- char c = '0' + a[id];
- dfs(s + c, id + 1, u + 1, a[id]);
- }
- }
- else if (u == 7) {
- if (a[id] <= 3) {
- char c = '0' + a[id];
- dfs(s + c, id + 1, u + 1, a[id]);
- }
- }
- else if (u == 8) {
- if (v == 3) {
- int num = (s[4] - '0') * 10 + s[5] - '0';
- if (mon[num] == 31 && a[id] <= 1) {
- char c = '0' + a[id];
- dfs(s + c, id + 1, u + 1, a[id]);
- }
- }
- else if (v == 0 && a[id] == 0) {
-
- }
- else {
- char c = '0' + a[id];
- dfs(s + c, id + 1, u + 1, a[id]);
- }
- }
-
- char c = '0' + a[id];
- dfs(s, id + 1, u, v);
- }
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(0);
-
- for (int i = 1; i <= 100; ++i) {
- cin >> a[i];
- }
- dfs("", 1, 1, 0);
- cout << st.size() << "\n";
- return 0;
- }
- #include<bits/stdc++.h>
- using namespace std;
- int a[100],ans;
- bool vis[20240000];
- bool check(int date){ //判断日期合法性
- if(vis[date]) return false;
- vis[date]=true;
- int mm=date/100%100;
- int dd=date%100;
- if(mm<1||mm>12)return false;
- if(mm==1||mm==3||mm==5||mm==7||mm==8||mm==10||mm==12){
- if(dd>=1&&dd<=31) return true;
- }else if(mm==2){
- if(dd>=1&&dd<=28)return true;
- }else if(dd>=1&&dd<=30)return true;
- else return false;
- }
-
- void dfs(int x,int pos,int date){ //x是当前枚举的下标,pos是当前枚举的位数,date是当前组成的日期
- if(x==100)return ;
- if(pos==8){
- if(check(date))++ans;
- return;
- }
- if((pos==0&&a[x]==2)|| //将每一位的合法情况进行判断
- (pos==1&&a[x]==0)||
- (pos==2&&a[x]==2)||
- (pos==3&&a[x]==3)||
- (pos==4&&a[x]>=0&&a[x]<=1)||
- (pos==5&&a[x]>=0&&a[x]<=9)||
- (pos==6&&a[x]>=0&&a[x]<=3)||
- (pos==7&&a[x]>=0&&a[x]<=9))
- dfs(x+1,pos+1,date*10+a[x]); //选择这个数
- dfs(x+1,pos,date); //不选这个数
- }
-
-
- int main()
- {
- ios::sync_with_stdio(0);cin.tie(0); //关闭流同步
- for(int i=0;i<100;i++)cin>>a[i];
- dfs(0,0,0);
- cout<<ans;
-
-
- return 0;
- }
答案:235
学会加工题目信息。如果有i个0,那么则有n-i个1.而且0必定比1出现少。所以枚举一半即可。然后可以化成
填空题枚举就行了!
- #include<bits/stdc++.h>
- using namespace std;
- typedef long double db;
- const db ans = 11625907.5798,eps=1e-4;
- const int N =23333333;
- int main()
- {
- for(int i=0;i<=N/2;i++) //0的个数
- {
- int u = N-i;
- db res=-1.0*u*u/N*log2(1.0*u/N)-1.0*i*i/N*log2(1.0*i/N);
- if(fabs(res-ans)<eps){
- cout<<i;
- return 0;
- }
- }
- return 0;
- }
答案:11027421
这题可能是我最有把握的题目了,一拿到题目,我就想到了逆向分析。然后明确了一个思路。拿一个MAXN数组和一个MINN数组分别保存取下界的值(然后再数组里找一个最小值),MINN数组保存上界值(然后取数组的最大值)。也不知道对不对,只去过了样例。
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- const int N = 10010;
- int MAXN[N], MINN[N];
- int n, k ;
- int main()
- {
-
- scanf("%d", &n);
- while (n--)
- {
- int a, b;
- scanf("%d%d", &a, &b);
- MAXN[k] = a / b;
- if ((a * 1.0 / (b + 1) > a / (b + 1)))MINN[k] = a / (b + 1) + 1;
- else MINN[k] = a / (b + 1);
- k++;
- }
- sort(MAXN, MAXN + k);
- sort(MINN, MINN + k);
- printf("%d %d", MINN[k - 1] ,MAXN[0]);
- return 0;
- }
- #include<bits/stdc++.h>
- using namespace std;
- const int MAX_N=1e4+1;
- int N,A[MAX_N],B[MAX_N];
- bool check_min(int V)
- {
- for(int i=1;i<=N;i++)
- if(A[i]/V>B[i])return false;
- else return true;
- }
-
- bool check_max(int V)
- {
- for(int i=1;i<=N;i++)
- if(A[i]/V<B[i])return false;
- return true;
- }
- int main()
- {
- ios::sync_with_stdio(0);cin.tie(0);
- cin>>N;
- for(int i=1;i<=N;i++)cin>>A[i]>>B[i];
-
- //二分答案过程
- int L=1,R=1000000000,V_min;
- while(L<=R)
- {
- int mid = (L+R)>>1;
- if(check_min(mid)){
- V_min=mid;
- R=mid-1;
- }else L=mid+1;
- }
- L=1,R=1000000000;int V_max;
- while(L<=R)
- {
- int mid=L+R>>1;
- if(check_max(mid)){
- V_max=mid;
- L=mid+1;
- }else R=mid-1;
- }
- cout<<V_min<<' '<<V_max;
-
- return 0;
-
- }
飞机降落问题,看到数据范围的时候,立马想到了贪心模型,想着用全排列的方式去做,数据规模大概在3*10^9,会超时,不过可以过大部分样例。思路是这样,但是考试真的不会写这种排列hh。现在我还记得考试前我复习到的一个全排列函数next_permutation。赛后听到大佬讲用dfs+剪枝的方法可以大大减小数据规模(如果前面某驾飞机已经判断不能降落了,那么就不用再向全排列一样继续枚举),然后跟着大佬去尝试写代码
- #include<bits/stdc++.h>
- using namespace std;
- const int N = 11;
- int T[N],D[N],L[N];
- bool used[N],have_answer; //是否尝试降落,是否有答案
- int n;
- void dfs(int x,int tim){ //已经降落了几架,现在所用时间
- if(have_answer) return; //找到答案,就跳出
- if(x==n){ //如果降落n架,有解
- have_answer=1;
- return;
- }
- for(int i=1;i<n;i++)
- if(!used[i]&&tim<T[i]+D[i]){ //没降落,而且现在花费的时间小于这架飞机的最大停留时间
- used[i]=1; //成功降落
- dfs(x+1,max(T[i],tim)+L[i]); //最早在T【i】时间降落,这里取个max值
- if(have_answer)return; //找到答案,跳出
- used[i]=0; //否则回复原样
- }
- }
-
- void solve(){
- have_answer=0; //开头默认没有解
- cin>>n;
- for(int i=1;i<=N;i++){
- cin>>T[i]>>D[i]>>L[i];
- used[i]=0;
- }
- dfs(0,0);
- if(have_answer)cout<<"YES\n";
- else cout<<"NO\n";
- }
-
- int main()
- {
- ios::sync_with_stdio(0);cin.tie(0);
- int t;
- cin>>t;
- while(t--) solve();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。