清北学堂国庆day5解题报告
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清北学堂国庆day5解题报告相关的知识,希望对你有一定的参考价值。
Day5解题报告
张炳琪
时间安排::
T1:想了很久,一个多小时写的暴力
T2:一小时左右
T3:一小时以内
答题情况和错误分析::
T1: 30
考场上没推出来,想复杂了,拆分的二进制只得了暴力分
T2:70
写的比较稳妥的根号枚举暴力
T3:60
写了个剪枝搜索,打了个暴力
Tot::160
题目解析:
T1:
先将数据从小到大排序,然后线性扫一遍,一边扫一边求和,当下一个数字比以前所求的所有数字之和还要大1以上的时候,就不满足情况,这时应当终止并且输出。
T2:
正解是二分最小单个连续值区间,O1计算两边的值
歪解是开根号乘以二再减一也能A
我的方法是一种找连续区间的方法,但只是枚举,所以过不了所有点
T3:从60%的数据中我们得到其实,这个题目搜索的复杂度已经不错了,但是2^30依旧过不了,这时用了一个我以前没用过的知识点,就是分成两块搜索,然后合并状态,听老师讲完就比较好写了;
合并的时候采用二分合并的方法,第一次搜索出所有状态后对于状态进行排序,首先按照钻石个数,其次按照拿到的价值,之后第二次搜索对于每个得到的状态二分找寻所有符合要求的条件
代码:
T1
#include<cstdio> #include<iostream> #include<algorithm> #define MAXN 100100 using namespace std; long long note[MAXN]; int n; int main() { freopen("lost.in","r",stdin);freopen("lost.out","w",stdout); scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%lld",¬e[i]); sort(note + 1,note + n + 1); long long tot = 0; for(int i = 1;i <= n;i++) { if(note[i] > tot + 1) { break; } tot += note[i]; } cout << tot + 1; return 0; }
T2:
#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> using namespace std; long long n; int main() { freopen("div.in","r",stdin);freopen("div.out","w",stdout); cin >> n; long long q = sqrt(n); long long ans = q * 2; if(q * (q + 1) > n)ans--; cout << ans ; return 0; }
T3;
#include<cstdio> #include<algorithm> using namespace std; struct Note{ int k; int ver; double gai; }note[923456]; double qian[31][9876]; int ver[31][9876]; int tp[31]; int top = 0; int n,m; int v[99]; double p[99]; double ans[99]; int zz; void dfs(int step,int zuan,int mon,double gai) { if(step == zz + 1) { top++; note[top].gai = gai; note[top].k = zuan; note[top].ver = mon; return; } dfs(step + 1,zuan + 1,mon,gai * (1 - p[step])); dfs(step + 1,zuan,mon + v[step],gai * p[step]); } int find(int k,int mon) { int l = 1,r = tp[k]; while(l + 1 < r) { int mid = (l + r) >> 1; if(ver[k][mid] >= mon)l = mid; else r = mid; } if(ver[k][r] >= mon)return r; if(ver[k][l] >= mon)return l; return -1; } void check(int zuan,int mon,double gai) { for(int i = 0;i <= n - zuan;i++) { int zz = m - mon; int q = find(i,zz); if(q == -1)continue; ans[i + zuan] += qian[i][q] * gai; } } void rdfs(int step,int zuan,int mon,double gai) { if(step == n + 1) { check(zuan,mon,gai); return; } rdfs(step + 1,zuan + 1,mon,gai * (1 - p[step])); rdfs(step + 1,zuan,mon + v[step],gai * p[step]); } bool cmp(Note a,Note b) { return a.k == b.k ? a.ver > b.ver : a.k < b.k; } int main() { freopen("diamond.in","r",stdin);freopen("diamond.out","w",stdout); scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++) { scanf("%d%lf",&v[i],&p[i]); p[i] /= 100.0; } zz = n / 2; dfs(1,0,0,1.0); sort(note + 1,note + top + 1,cmp); for(int i = 1;i <= top;i++) { tp[note[i].k]++; ver[note[i].k][tp[note[i].k]] = note[i].ver; qian[note[i].k][tp[note[i].k]] = qian[note[i].k][tp[note[i].k] - 1] + note[i].gai; } rdfs(zz+1,0,0,1.0); for(int i = 0;i <= n;i++) printf("%.3lf\n",ans[i]); return 0; }
以上是关于清北学堂国庆day5解题报告的主要内容,如果未能解决你的问题,请参考以下文章