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

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. 认识并学会springCloud的使用

    SpringCloud将现在一些流行的技术整合到一起,实现如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能.主要涉及的组件有 netflix Eureka:注册中心 Zu ...

  2. Luogu P5221 Product

    题目 注意一下空间限制. 令\(f(n)=\prod\limits_{i=1}^n\prod\limits_{j=1}^nij,g(n)=\prod\limits_{i=1}^n\prod\limit ...

  3. git clone 含有子模块的项目

    当一个 git 项目包含子模块(submodule) 时,直接克隆下来的子模块目录里面是空的. 有两种方法解决: 方法一 如果项目已经克隆到了本地,执行下面的步骤: 初始化本地子模块配置文件 git ...

  4. Spring防止Xss配置

    web.xml配置 <!-- xss过滤器 --> <filter> <filter-name>XssFilter</filter-name> < ...

  5. 112、如何使用stack (Swarm19)

    参考https://www.cnblogs.com/CloudMan6/p/8135714.html   定义好了 stack YAML 文件,就可以通过 docker stack deploy 命令 ...

  6. QT多线程同步之QWaitcondition

    使用到多线程,无可避免的会遇到同步问题,qt提供几种同步线程的方法,在这里讲一下QWaitcondition的简单使用. 一.QWaitcondition,是通过一个线程达到某种条件来唤起另一个线程来 ...

  7. pt-archiver配置自动归档

    Mysql的数据归档通常使用percona的pt-archiver.通过shell脚本加crontab可以应对大多数场景下的数据自动归档. 安装 Percona Toolkit的安装不再赘述,请自行搜 ...

  8. vscode常用插件列表

    vscode插件 备注 Markdown PDF 把markdown文件转换成别的文件 Markdown TOC markdown文件目录生成 PHP Debug PHP调试 PHP Intenlli ...

  9. php不重新编译,添加模块

    本文已安装mysqli模块为例 一:检查 1:首先保证php-fpm能正常启动 2:查看当前已安装的php模块是否有mysqli [root@oldboyedu ~]# /application/ph ...

  10. Linux学习篇之OpenKM的安装(汉化)

    OpenKM是一个开放源代码的电子文档管理系统,它的特点是可用于大型公司或是中小企业, 适应性比较强. 并且在知识管理方面的加工,提供了更加灵活和成本较低的替代应用,下面讲一下搭建方法. 一.以下都是 ...