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

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. SpringDataRedis配置

    1.父pom.xml配置依赖包 <dependencyManagement> <dependencies> <dependency> <groupId> ...

  2. ZooKeeper常用命令行操作

    ZooKeeper常用命令行操作 通过./zkCli.sh 打开zk的客户端进入命令行后台 ls/ls2 列出当前节点下的子节点 ls2还会列出当前节点的状态 [zk: localhost:2181( ...

  3. 简单了解运用Git

    Git是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的分布式版本控制系统. SVN是集中式的. Git没有中央服务器,每台电脑就是一个完整的版本库 ,工作无需 ...

  4. 两两内积为0(牛客多校第七场)-- CDMA

    题意: 构造一个n*n的矩阵,元素只能是-1或1,任意两行内积为0(两两相乘加起来和为0). 思路: #define IOS ios_base::sync_with_stdio(0); cin.tie ...

  5. Postman之前言

    Postman是一款流行的接口api调试/测试工具.几乎可以发送大多数的HTTP请求. 1.依据开发提供的接口文档,对接口进行测试. 2.如果是自己学习,可以网上找一些免费的接口进行学习,或者抓包 - ...

  6. 使用mybatis插件自动生成代码以及问题处理

    1.pom.xml中加入依赖插件 <!-- mybatis generator 自动生成代码插件 --> <plugin> <groupId>org.mybatis ...

  7. luogu P2154 [SDOI2009]虔诚的墓主人

    luogu 下面记一个点上下左右点数分别为\(u_i,d_i,l_i,r_i\) 枚举每个中间点太慢了,考虑枚举两个点之间横的一条线段,这里面的点左边点数目都相同,右边点数目都相同,然后只要查一下区间 ...

  8. 学会这 2 点,轻松看懂 MySQL 慢查询日志

    MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1)通用查询日志:记录建立的客户端连接和执行的语句. 2)慢查 ...

  9. Scala新版本学习(1):

    1.进官网:https://www.scala-lang.org/ 上面就是进入Scala社区后的一个画面,官方对Scala的简单介绍是:Scala将面向对象和函数式编程集合在一个简洁的高级语言中,S ...

  10. jquery 滚动事件-记录自己常用的

    1.h5端页面滑动至第3屏及以后才出现置顶按钮 $(document).scroll(function() { var scroH = $(document).scrollTop(); //滚动高度 ...