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

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. 【转帖】Gitlab 从 12.1 版本开始将不再支持 MySQL !

    Gitlab 从 12.1 版本开始将不再支持 MySQL ! Gitlab 官方宣布,将从 12.1 版本开始不再支持 MySQL 数据库. http://news.51cto.com/art/20 ...

  2. Selenium在IE浏览器中执行脚本时输入字符太慢问题解决方法

    问题描述: IE浏览器中执行Selenium脚本的时候发现输入文本的时候总是一个字符一个字符的输入,并且输入每个字符之间都隔几秒.   解决方案: 将使用的IE浏览器驱动由64位的换成32位的.

  3. requests库爬取豆瓣热门国产电视剧数据并保存到本地

    首先要做的就是去豆瓣网找对应的接口,这里就不赘述了,谷歌浏览器抓包即可,然后要做的就是分析返回的json数据的结构: https://movie.douban.com/j/search_subject ...

  4. FullPage.js全屏插件文档及使用方法

    简介 fullPage.js是一个基于jQuery的全屏滚动插件,它能够很方便.很轻松的制作出全屏网站 下载地址 下载地址 相关示例:基于fullpage.js实现的360全屏滑动效果 支持功能 支持 ...

  5. Redis5版本集群搭建

    一.简介 1.1 Redis是什么 Redis是一个开源的,使用ANSI C 编写,高性能的Key-Value的NoSQL数据库. 1.2 Redis特点 (1)基于内存 (2)可持久化数据 (3)具 ...

  6. tomcat启动报ClassNotFound

    排除本来就缺少该类的原因,经过自己经验和网上查的资料,解决方式如下: jar包冲突(关闭其他项目) eclipse的java版本不对,点击项目,右键properties在project facets, ...

  7. session+验证码 学习

    分析 LoginServlet类 @WebServlet("/loginServlet") public class LoginServlet extends HttpServle ...

  8. vue+element 使用Export2Excel导出表格组件

    下载表格组件是根据我自己的业务需求来封装的 使用的是vue中 xlsx 的插件,需要安装新的依赖及配置 仅供参考 不保证和你百分百匹配 安装依赖 npm install -S file-saver x ...

  9. $store.getters调用不执行

    $store.getters调用不执行 api:https://vuex.vuejs.org/zh/guide/getters.html 场景: 在登录时将登录得到的用户信息存储在vuex的state ...

  10. Java---- 静态内部类与非静态内部类的区别

    静态类(只有内部类才能被声明为静态类,即静态内部类)1.只能在内部类中定义静态类 2.静态内部类与外层类绑定,即使没有创建外层类的对象,它一样存在. 3.静态类的方法可以是静态的方法也可以是非静态的方 ...