一些简单题(1)(Source : NOIP历年试题+杂题)
最近也写了些许题目吧,还是写写博客,捋捋思路。
求一个$a \times b(a,b \leq 10^3)$的矩阵,求出一个$n \times n (n \leq 100)$的矩阵,设矩阵中元素最小值$Min$,最大值$Max$,
最小化$Max - Min$
Sol : 这个题事实上只需要暴力扫每个子矩阵即可。复杂度是$O(abn)$
预处理对点$(i,j)$的$ Max[i][j] = \max\limits_{k=i-n+1}^{i} a[k][j]$
枚举每个子矩阵的时候,求$(i,j)$为左下角的$n \times n$子矩阵的
$MAX=\max\limits_{k=j-n+1}^{j} Max[i][k]$而$MIN$的处理同理。
- // luogu-judger-enable-o2
- # include<bits/stdc++.h>
- # define int long long
- using namespace std;
- const int N=1e3+;
- int w[N][N];
- int Max[N][N],Min[N][N];
- int a,b,n,ans=0x3f3f3f3f;
- signed main()
- {
- scanf("%lld%lld%lld",&a,&b,&n);
- for (int i=;i<=a;i++)
- for (int j=;j<=b;j++)
- scanf("%lld",&w[i][j]);
- memset(Max,-0x3f,sizeof(Max));
- memset(Min,0x3f,sizeof(Min));
- for (int i=;i<=a;i++)
- for (int j=;j<=b;j++) {
- if (j<n) continue;
- for (int k=j;k>=j-n+;k--)
- Min[i][j]=min(Min[i][j],w[i][k]),
- Max[i][j]=max(Max[i][j],w[i][k]);
- }
- for (int i=;i<=a;i++)
- for (int j=;j<=b;j++) {
- int mi=0x3f3f3f3f,ma=-0x3f3f3f3f;
- if (i<n) continue;
- for (int k=i;k>=i-n+;k--)
- mi=min(mi,Min[k][j]),ma=max(ma,Max[k][j]);
- if (ma-mi<ans&&ma-mi>=) ans=ma-mi;
- }
- printf("%lld\n",ans);
- return ;
- }
P2216.cpp
有$n(n \leq 18 )$个小猪在平面直角坐标系中,小鸟可以从$(0,0)$出发以一条任意的$y = ax^2 + bx + c(a<0)$的抛物线消去飞行路线上的猪。
如要消除所有的猪,最小化所需鸟的个数。
Sol : 数据范围是搜索的复杂度,加最优性剪枝能过。
dfs(a,b,c)表示当前选择第$a$只猪,前确定了$b$条解析式,前面$c$只猪是单着被打中的(还没有确定一条解析式)
那么对于这只猪有三种决策:
A. 单独使用一只鸟击中。 B. 被之前确定的一条解析式打中。 C. 和之前某一只猪构成抛物线(三点构成一条抛物线)
然后就搜索就可以了, 加上最优性剪枝b+c > ans 直接return;
vector可以快速插入和删除好评!!!!
样例没过却AC的代码好评:https://www.luogu.org/recordnew/show/19042160
- # include <bits/stdc++.h>
- using namespace std;
- const int N=;
- const double eps=1e-;
- struct rec{
- double x,y;
- }w[N];
- int n,ans;
- vector<int>single;
- vector<pair<double,double> >pwx;
- void dfs(int a,int b,int c)
- {
- if (b+c>=ans) return;
- if (a>n) { ans=min(ans,b+c); return;}
- single.push_back(a); dfs(a+,b,c+); single.pop_back();
- bool ff=false;
- for (int i=;i<pwx.size();++i) {
- double pa=pwx[i].first,pb=pwx[i].second;
- if (fabs(pa*w[a].x*w[a].x+pb*w[a].x-w[a].y)<=eps) {
- dfs(a+,b,c);
- ff=true; break;
- }
- }
- if (ff) return;
- for (int i=;i<single.size();++i) {
- int id=single[i];
- if (fabs(w[a].x-w[id].x)<=eps) continue;
- double pa=(w[a].y*w[id].x-w[id].y*w[a].x)/(w[a].x*w[id].x*(w[a].x-w[id].x));
- double pb=(w[a].y-pa*w[a].x*w[a].x)/w[a].x;
- if (pa>=0.0) continue;
- single.erase(single.begin()+i);
- pwx.push_back(make_pair(pa,pb));
- dfs(a+,b+,c-);
- single.insert(single.begin()+i,id);
- pwx.pop_back();
- }
- }
- int main()
- {
- int T; scanf("%d",&T);
- while (T--) {
- ans=0x3f3f3f3f; single.clear(); pwx.clear();
- int t; scanf("%d%d",&n,&t);
- for (int i=;i<=n;i++) scanf("%lf%lf",&w[i].x,&w[i].y);
- dfs(,,);
- printf("%d\n",ans);
- }
- return ;
- }
P2831.cpp
求方程$\frac{1}{x} +\frac{1}{y} = \frac{1}{n} \ \ \ x,y,n \in N^*$ 的解$(x,y) $其中$(x\leq y)$的组数。
对于100%的数据$n \leq 10^{14}$
Sol : 通分,得出 $nx + ny - xy = 0$ 构造得$(n-x)(n-y) = n^2$
等价于求$d(n^2)$ 然后发现$n^2$的比较大无法质因数分解,考虑对$n$分解质因数。
$ n = \sum\limits_{i=1}^{k} {a_i} ^ {p_i}$ 则 $n^2 = (\sum\limits_{i=1}^{k} {a_i} ^ {p_i})^2 = \sum\limits_{i=1}^{k} {a_i} ^ {2p_i}$
所以$d(n^2) = \prod\limits_{i=1}^{k} (2p_i + 1)$
- # include <bits/stdc++.h>
- # define int long long
- using namespace std;
- const int N=1e7+;
- int pr[N];
- bool is_pr[N];
- void EouLaSha(int Lim)
- {
- memset(is_pr,true,sizeof(is_pr));
- is_pr[]=false;
- for (int i=;i<=Lim;i++) {
- if (is_pr[i]) pr[++pr[]]=i;
- for (int j=;j<=pr[]&&i*pr[j]<=Lim;j++) {
- is_pr[i*pr[j]]=false;
- if (i%pr[j]==) break;
- }
- }
- }
- signed main()
- {
- EouLaSha(1e7);
- int n; scanf("%lld",&n);
- int ret=;
- for (int i=;i<=pr[];i++)
- if (n%pr[i]==) {
- int times=;
- while (n>&&n%pr[i]==) times++,n/=pr[i];
- ret=ret*(*times+);
- }
- if (n>) ret=ret*(+);
- printf("%lld\n",(ret+)>>);
- return ;
- }
P5253.cpp
一棵$n(n \leq 5\times 10^4)$个节点的树上有$m (m \leq 5 \times 10^4)$个障碍,每个障碍可以移动,移动的代价就是树上最短路长度。
最小化移动这些障碍的最大代价使得从根节点$1$走到树的叶子节点的路径所构成集合为$\varnothing $
Sol :最小最大\最大最小 显然考虑二分答案。
对于一个合法的最大移动步数$Mid$,考虑怎么移动可以控制的叶子结点更多?
这个节点的目的地深度尽可能小。但是需要考虑过根节点$1$的可能。
标记节点可以到达$1$时,可能走到达和$1$相连的直接儿子,控制这棵子树。我们称之为帮助别人。
如果这个节点无法到达$1$,那么显然只需要让他到达他所能跳上来的深度最小的节点就行了,这样就可以控制最广阔的叶子。
如果我们经过这些处理以后,我们发现和$1$相连的某些节点所在子树的叶子无法被完全覆盖,那么我们称这个节点是需要帮助的。
显然一个需要帮助的节点需要一个帮助别人的节点的帮助。
若帮助别人的节点自己的子树还未完全覆盖,而且这个帮助别人的路径不足以重新到达自己所在的节点(相当于这个节点和1之间的路径走了2次),那么我们把这个节点取覆盖其所在子树的那个区间。
这是因为,如果不这样做,势必需要另外一个比当前帮助的长度要更长的帮助别人的节点来帮助,而不帮助自己的那个节点帮助别人的能力却比帮助这个节点的另外一个帮助者要差。这样比上述的方案更劣。
然后对剩余的需要帮助的节点和可以提供帮助的距离进行排序双指针判断是否可以覆盖即可。
树上向上跳可以用倍增优化。
复杂度是$O(m log_2 {n} log_2{w})$
- // luogu-judger-enable-o2
- # include<bits/stdc++.h>
- # define int long long
- using namespace std;
- const int N=1e5+;
- bool mark[N];
- int d[N][],b[N],g[N][],help[N],tmp[N];
- int size[N],n,m;
- vector<int>rec[N];
- struct rec{
- int pre,to,w;
- }a[N<<];
- int head[N],tot;
- void dfs1(int u,int fa)
- {
- size[u]=; g[u][]=fa;
- for (int i=head[u];i;i=a[i].pre) {
- int v=a[i].to; if (v==fa) continue;
- d[v][]=a[i].w;
- dfs1(v,u);
- size[u]+=size[v];
- }
- }
- void init()
- {
- dfs1(,);
- for (int i=;i<=;i++)
- for (int j=;j<=n;j++)
- g[j][i]=g[g[j][i-]][i-],
- d[j][i]=d[j][i-]+d[g[j][i-]][i-];
- }
- void adde(int u,int v,int w)
- {
- a[++tot].pre=head[u];
- a[tot].to=v;
- a[tot].w=w;
- head[u]=tot;
- }
- bool dfs2(int u,int fa)
- {
- if (mark[u]) return true;
- if (size[u]==) {
- if (mark[u]) return true;
- else return false;
- }
- bool flag=true;
- for (int i=head[u];i;i=a[i].pre) {
- int v=a[i].to;
- if (v==fa||mark[v]) continue;
- flag&=dfs2(v,u);
- }
- return flag;
- }
- bool check(int Mid)
- {
- memset(mark,false,sizeof(mark));
- for (int i=;i<=n;i++) rec[i].clear();
- for (int i=;i<=m;i++) {
- int dist=,u=b[i];
- for (int j=;j>=;j--)
- if (g[u][j]>&&dist+d[u][j]<=Mid) {
- dist+=d[u][j]; u=g[u][j];
- }
- if (g[u][]==) {
- dist+=d[u][];
- if (dist>Mid) mark[u]=true;
- else {
- rec[u].push_back(Mid-dist);
- }
- } else mark[u]=true;
- }
- for (int i=;i<=n;i++) sort(rec[i].begin(),rec[i].end());
- help[]=;
- for (int i=head[];i;i=a[i].pre) {
- int v=a[i].to; if (dfs2(v,)) continue;
- bool flag=true;
- for (int j=;j<rec[v].size();j++)
- if (rec[v][j]<a[i].w) { rec[v].erase(rec[v].begin()+j);flag=false;break;}
- if (!flag) continue;
- help[++help[]]=a[i].w;
- }
- tmp[]=;
- for (int i=head[];i;i=a[i].pre) {
- int v=a[i].to;
- for (int j=;j<rec[v].size();j++)
- tmp[++tmp[]]=rec[v][j];
- }
- sort(tmp+,tmp++tmp[]);
- sort(help+,help++help[]);
- if (help[]==) return true;
- int pt1=,pt2=;
- while (pt1<=tmp[]) {
- if (pt2>help[]) return true;
- while (tmp[pt1]>=help[pt2]&&pt2<=help[]&&pt1<=tmp[]) pt1++,pt2++;
- if (pt2>help[]) return true;
- pt1++;
- }
- return false;
- }
- signed main()
- {
- scanf("%lld",&n);
- int l=,r=,ans=-;
- for (int i=;i<n;i++) {
- int u,v,w; scanf("%lld%lld%lld",&u,&v,&w); r+=w;
- adde(u,v,w); adde(v,u,w);
- }
- scanf("%lld",&m);
- for (int i=;i<=m;i++) scanf("%lld",&b[i]);
- init();
- while (l<=r) {
- int mid=(l+r)>>;
- if (check(mid)) ans=mid,r=mid-;
- else l=mid+;
- }
- printf("%lld\n",ans);
- return ;
- }
P1084.cpp
一些简单题(1)(Source : NOIP历年试题+杂题)的更多相关文章
- 一些简单题(2)(Source : NOIP历年试题+杂题)
P3084 [USACO13OPEN]照片Photo 给出$m$个区间$[l_i,r_i]$覆盖$S=[1,n]$,试确定最大特殊点的数使得这每一个区间覆盖且仅覆盖一个特殊点. 如果无解,输出$-1$ ...
- NOIP 历年试题大致考点总结
总的来说,水平还不够-- 要努力了! NOIP2012 D1T1 模拟, 字符串 D1T2 贪心, 数学 (推导贪心策略), 高精度 D1T3 unsolved 开车旅行 倍增 D2T1 解线性模方程 ...
- noip历年试题
noip2018 铺设道路 货币系统 赛道修建 一眼贪心.随便实现. 旅行 环套树枚举删除环上哪条边. 填数游戏 找规律,这谁会啊. 保卫王国 动态Dp,去问这位神仙. noip2017 小凯 ...
- 2016 10 26考试 NOIP模拟赛 杂题
Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- 剑指Offer——网易校招内推笔试题+模拟题知识点总结
剑指Offer--网易校招内推笔试题+模拟题知识点总结 前言 2016.8.2 19:00网易校招内推笔试开始进行.前天晚上利用大约1小时时间完成了测评(这个必须做,关切到你能否参与面试).上午利用2 ...
- NOIP前的刷题记录
因为这几天要加油,懒得每篇都来写题解了,就这里记录一下加上一句话题解好了 P4071 [SDOI2016]排列计数 组合数+错排 loj 6217 扑克牌 暴力背包 P2511 [HAOI2008 ...
- CCF认证历年试题
CCF认证历年试题 不加索引整理会死星人orz 第一题: CCF201712-1 最小差值(100分) CCF201709-1 打酱油(100分) CCF201703-1 分蛋糕(100分) CCF2 ...
- 11.14 noip模拟试题
题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer ...
随机推荐
- 如何重装mysql8及初次修改密码
首先在设置里卸载旧版的mysql 然后把你之前的安装的mysql文件夹整个删掉 然后删除注册表的MySQL信息 安装新版的MySQL 新建并配置my-default.ini文件 如下: [mysqld ...
- MySQL 如何更改某一用户及伞下成员的path
MySQL 如何更改某一用户及伞下成员的path 在有的系统中,推荐关系的维护不只是pid那么简单,为了某些业务,可能还会需要维护path字段,path字段的存在,优点在于查询方便,最起码不用递归了 ...
- 从入门到自闭之Python函数初识
函数初识 定义:def--关键字 将某个功能封装到一个空间中就是一个函数 功能: 减少重复代码 函数的调用 函数名+():调用函数和接收返回值 函数的返回值 return 值 == 返回值 ...
- java检测是不是移动端访问
request可以用别的代替 private static boolean isMobile(){ HttpServletRequest request = ThreadContextHolder.g ...
- Nginx启动错误 Failed to read PID from file /run/nginx.pid 的处理方法
问题产生原因 因为 nginx 启动需要一点点时间,而 systemd 在 nginx 完成启动前就去读取 pid file 造成读取 pid 失败 解决方法 让 systemd 在执行 ExecSt ...
- windows10升级更新1709版本 在桌面和文件夹中点击右键刷新,会引起卡顿反应慢
win10,升级更新,1709,右键,卡机,刷新,反应慢,桌面,文件夹 windows自动升级到1709版本后出现的问题,而之前是没有这种问题的. 最终解决办法:(需要设置注册表) 运行:快捷键Win ...
- snappy-java两种压缩方式的区别
1.Snappy-java项目地址 https://github.com/xerial/snappy-java 2.Snappy-java两种压缩方式 使用Snappy.compress进行压缩 St ...
- jq sku实现
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 从FBV到CBV二(认证器)
span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror ...
- no input file specified 三种解决方法
一.IIS Noinput file specified 方法一:改PHP.ini中的doc_root行,打开ini文件注释掉此行,然后重启IIS 方法二: 请修改php.ini 找到 ; cgi.f ...