最近也写了些许题目吧,还是写写博客,捋捋思路。

P2216 [HAOI2007]理想的正方形

求一个$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

P2831 [NOIP2016D2T3] 愤怒的小鸟

有$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

P5253 丢番图

求方程$\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

P1084 [NOIP2012D2T3] 疫情控制

一棵$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历年试题+杂题)的更多相关文章

  1. 一些简单题(2)(Source : NOIP历年试题+杂题)

    P3084 [USACO13OPEN]照片Photo 给出$m$个区间$[l_i,r_i]$覆盖$S=[1,n]$,试确定最大特殊点的数使得这每一个区间覆盖且仅覆盖一个特殊点. 如果无解,输出$-1$ ...

  2. NOIP 历年试题大致考点总结

    总的来说,水平还不够-- 要努力了! NOIP2012 D1T1 模拟, 字符串 D1T2 贪心, 数学 (推导贪心策略), 高精度 D1T3 unsolved 开车旅行 倍增 D2T1 解线性模方程 ...

  3. noip历年试题

      noip2018 铺设道路 货币系统 赛道修建 一眼贪心.随便实现. 旅行 环套树枚举删除环上哪条边. 填数游戏 找规律,这谁会啊. 保卫王国 动态Dp,去问这位神仙.   noip2017 小凯 ...

  4. 2016 10 26考试 NOIP模拟赛 杂题

    Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...

  5. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  6. 剑指Offer——网易校招内推笔试题+模拟题知识点总结

    剑指Offer--网易校招内推笔试题+模拟题知识点总结 前言 2016.8.2 19:00网易校招内推笔试开始进行.前天晚上利用大约1小时时间完成了测评(这个必须做,关切到你能否参与面试).上午利用2 ...

  7. NOIP前的刷题记录

    因为这几天要加油,懒得每篇都来写题解了,就这里记录一下加上一句话题解好了 P4071 [SDOI2016]排列计数   组合数+错排 loj 6217 扑克牌 暴力背包 P2511 [HAOI2008 ...

  8. CCF认证历年试题

    CCF认证历年试题 不加索引整理会死星人orz 第一题: CCF201712-1 最小差值(100分) CCF201709-1 打酱油(100分) CCF201703-1 分蛋糕(100分) CCF2 ...

  9. 11.14 noip模拟试题

      题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer ...

随机推荐

  1. Eclipse中格式化代码

    Eclipse中格式化代码快捷键Ctrl+Shift+F失效的解决办法 格式化代码的时候,右键 --> Source --> Format 能够起效,但 Ctrl+Shift+F不好使. ...

  2. MySQL之无限级分类表设计

    首先查找一下goods_cates表和table_goods_brands数据表 分别使用命令: root@localhost test>show columns from goods_cate ...

  3. Codeforces 1221F. Choose a Square

    传送门 对于某个点 $(x,y)$ ,不妨设 $x<y$ 因为如果 $x>y$ 直接按 $y=x$ 对称一下即可 当且仅当正方形左下角 $(a,a)$ 满足 $a<=x$,右上角 $ ...

  4. python:enumerate 函数

    说明 enumerate()是python的内置函数: 对于一个可迭代的(iterable)/可遍历的对象(如列表.字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值 多用于 ...

  5. 常见Http访问错误小结

    4xx 客户端错误# 400 bad request 错误的请求 # 401 未携带身份信息 # 403 forbidden 权限不够 # 404 Not Found# 405 请求方式不允许 5xx ...

  6. springboot(十七)-使用Docker部署springboot项目

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...

  7. 【lucene】一个简单的招聘网站的建立

    1.建立索引库: 核心代码如下 package com.tabchanj.job.index; import java.util.ArrayList; import java.util.HashMap ...

  8. 帝国cms 通过文章的id获取信息

    获取栏目id为13下id为46的数据 [e:loop={"select * from phome_ecms_news where classid = 13 and id = 46" ...

  9. 会计凭证替代 OBBH

    单词:Validation: 会计凭证校验 ,Substitution:会计凭证替代 step1: GCX2 gblr: ZRFI_GGBR000 gbls: ZRFI_GGBS000 - step2 ...

  10. Js 将图片的绝对路径转换为base64编码(3)

    图片文件改变一方法:$('#file').change(function(){var oFReader = new FileReader();oFReader.readAsDataURL(this.f ...