2019.8.7 NOIP模拟测试14 反思总结
先扔代码
调完自闭网络流了,新一轮考试前看看能不能赶完……
考得极其爆炸,心态也极其爆炸,真的是认识到自己能力上的不足
思维跑偏,代码能力差
就这样吧,再努力努力,不行就AFO
T1旋转子段:
因为我和正解的绝缘性,我上来先选择想暴力,搞了搞把暴力优化到n2,行了,就交了
大约是想正解的时候被奇怪的问题hack掉没有解决,于是被踢出了正解门外
这边正解用的是O(n)的做法。一个可以成为答案的旋转子段,如果它的两个端点旋转以后没有一个成为固定点,那么缩短这个子段的长度直到端点出现旋转以后的固定点,和一开始的子段是等价的。那么显然可以发现我们的答案子段只可能是[min(1,a1),max(1,a1)],[min(2,a2),max(2,a2)]...一共n个区间,把问题转化成检查这n个区间的答案。
从左到右扫一遍,把当前位置的值和下标都扔进桶里。当桶中某个地方已经被扔进第二次的时候,证明出现了一个右端点,然后进行check。记下每个a[i]对应的位置p[i],如果桶里满了的是当前位置的下标i,就利用p[i]计算旋转中心。如果满了的是a[i],a[i]的值就是它对应的左端点下标,一样可以直接计算。因为旋转中心分数值位置以及中间的空隙位置两种,所以这里算旋转中心的时候直接用左右端点加起来,不/2。
算出左端点以及旋转中心以后,只需要知道这个旋转中心在这个范围内已经贡献了几个答案,以及这段区间内原来有多少固定点,就能算出现在得出的答案是多少。因为对于同一个旋转中心,它之前能累计的答案区间右端点一定在当前右端点之前,范围被包含在当前范围之内,所以可以直接把之前扫到的完整区间都扔进旋转中心的桶里【仍然是左端点+右端点来避免空隙的误差】。而这段区间内原来有多少固定点,读入序列的时候就可以用前缀和算出。那么当前的答案就是旋转中心的桶里累计的答案+全局原有固定点减去这一段原有固定点+1。最后再把旋转中心的答案桶+1。
这样扫过去,就可以O(n)地更新出最优答案。
#include<iostream>
#include<cstdio>
using namespace std;
int sum,ans,c[];
int n,a[],b[],p[],v[];
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[i]=b[i-]+(a[i]==i?:);
p[a[i]]=i;
}
for(int i=;i<=n;i++){
sum=;
v[i]++;
v[a[i]]++;
if(v[i]==&&a[i]!=i){
int pos=i+p[i];
sum=sum+c[pos]+b[n]-(b[i]-b[p[i]-])+;
c[pos]++;
ans=max(ans,sum);
}
sum=;
if(v[a[i]]==&&a[i]!=i){
int pos=i+a[i];
sum=sum+c[pos]+b[n]-(b[i]-b[a[i]-])+;
c[pos]++;
ans=max(ans,sum);
}
if(a[i]==i){
ans=max(ans,);
c[i+a[i]]++;
}
}
printf("%d",max(ans,b[n]));
return ;
}
T2走格子:
考试的时候想岔了,不是说在一个位置就可以直接跳到四个方向最近的墙,而是可以向四个方向都只用走离最近的一个方向的墙+1的步数。
更正确的思路是可以向四个方向走离最近的一堵墙+1的距离【墙可以不在四个方向而是斜着在周围】,但可以证明两种方法是等价的,步数相同。
那么直接用第一种方法,对于每个点找出四个方向离它最近的墙的距离,向四个方向直着最远能走到的地方都连这个距离+1的边权。并且向周围的四个格子也都连1的边权【一步一步走】。
然后跑一个最短路就OK了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,a[][],sx,sy,ex,ey;
int h[]={,,-,,};
int l[]={,-,,,};
char c[][];
int ver[],head[],Next[],edge[],tot,vis[],dis[];
queue<int>q;
void add(int x,int y,int z){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
edge[tot]=z;
}
void SPFA(){
memset(dis,0x3f3f3f3f,sizeof(dis));
int u=(sx-)*m+sy;
dis[u]=;
q.push(u);
while(q.size()){
int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i],z=edge[i];
if(dis[v]>dis[u]+z){
dis[v]=dis[u]+z;
if(!vis[v]){
vis[v]=;
q.push(v);
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",c[i]+);
for(int j=;j<=m;j++){
if(c[i][j]=='C')sx=i,sy=j,a[i][j]=;
else if(c[i][j]=='F')ex=i,ey=j,a[i][j]=;
else if(c[i][j]=='.')a[i][j]=;
}
}
int xx[],yy[],val;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(!a[i][j])continue;
val=0x3f3f3f3f;
for(int fx=;fx<=;fx++){
int x=i,y=j;
while(a[x+h[fx]][y+l[fx]]){
x+=h[fx],y+=l[fx];
}
xx[fx]=x,yy[fx]=y;
val=min(val,abs(x-i)+abs(y-j));
}
for(int fx=;fx<=;fx++){
if(xx[fx]!=i||yy[fx]!=j){
add((i-)*m+j,(xx[fx]-)*m+yy[fx],val+);
// add((xx[fx]-1)*m+yy[fx],(i-1)*m+j,val+1);
}
if(a[i+h[fx]][j+l[fx]]){
add((i-)*m+j,(i+h[fx]-)*m+j+l[fx],);
// add((i+h[fx]-1)*m+j+l[fx],(i-1)*m+j,1);
}
}
}
}
SPFA();
if(dis[(ex-)*m+ey]<0x3f3f3f3f)printf("%d",dis[(ex-)*m+ey]);
else printf("no");
return ;
}
唔,千万不能连双向边,尤其是传送门那个地方…我简直就是个睿智。
T3柱状图:
考试的时候一看题目公式:决策单调性?
我大约没有救了。
正解是把枚举n,枚举高度h,再枚举n验证的暴力O(nhn)优化。高度h的答案是一个单峰函数,中间可能是平顶但是不影响这个平顶代表的答案就是最优的,所以可以三分。验证的n可以推一个式子,然后用平衡树或者树状数组优化到logn。
但是我不会写三分【虽然挺快就学会了】,也不想打后面树状数组一堆麻烦操作,或者稍微不麻烦点两棵平衡树。所以我跟机房里大部分人一样打了个模拟退火。
check函数是O(n)的,所以模拟退火不能跑太多次。check的O(n)做法就是,把所有数减去一个等差数列,把问题转化成填平一段序列。然后填平的最优高度一定是这段序列的中位数。如果这个中位数小于等于0就不满足题意,让它等于1。
然后因为long long等正确性问题死了好几次,调参倒是挺快就过了【可能是因为前人经验】。
模拟退火的板子还得再背几遍…
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n;
long long a[],b[],vis[];
double d[]={-1.0,1.0};
double T=,eps=0.1,delta=0.986;
long long C(int x){
long long maxx=max(x-,n-x);
long long sum=;
for(int i=;i<=n;i++){
b[i]=a[i]-(maxx-abs(x-i));
}
int mid=(+n)/;
nth_element(b+,b+mid,b+n+);
long long y=b[mid];
if(y<=)y=;
for(int i=;i<=n;i++){
sum=sum+abs(b[i]-y);
}
return sum;
}
void solve(){
long long ans=C();
int x=;
vis[]=;
while(T>eps){
int nowx=-;
nowx=((int)(x+d[rand()%]*T*rand()/RAND_MAX)%n+n)%n+;
if(vis[nowx]){
T*=delta;
continue;
}
long long sum=C(nowx);
long long cha=ans-sum;
if(cha>=){
ans=sum;
x=nowx;
}
else if(exp(cha/T)>(double)rand()/(double)RAND_MAX){
x=nowx;
}
vis[nowx]=;
T*=delta;
}
printf("%lld",ans);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%lld",&a[i]);
solve();
return ;
}
好居然写完了,滚了滚了。
洛谷今日运势:忌考试,忌刷题。
轻轻扣下一个问号
2019.8.7 NOIP模拟测试14 反思总结的更多相关文章
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- 2019.8.12 NOIP模拟测试18 反思总结
写个博客总是符合要求的对吧 回来以后第一次悄悄参加考试,昨天全程围观… 然后喜提爆炸120分wwwwwwwww T1用了全机房最慢的写法,导致改掉死循环T掉的一个点以后还是死活过不了最后一个点.T2全 ...
- 2019.8.10 NOIP模拟测试16 反思总结【基本更新完毕忽视咕咕咕】
一如既往先放代码,我还没开始改… 改完T1滚过来了,先把T1T2的题解写了[颓博客啊] 今天下午就要走了,没想到还有送行的饯别礼,真是欣喜万分[并没有] 早上刚码完前面的总结,带着不怎么有希望的心情开 ...
- 2019.7.27 NOIP模拟测试9 反思总结
先来整理题目 T1题目大意:给出n个数字和一个质数作为模数,一个变量x初始值为1.进行m次操作,每次让x随机乘上n个数中的一个,问m次操作以后x的期望值. 答案一定可以用分数表示,输出分子乘分母逆元的 ...
- 2019.8.13 NOIP模拟测试19 反思总结
最早写博客的一次∑ 听说等会儿还要考试[真就两天三考啊],教练催我们写博客… 大约是出题最友好的一次[虽然我还是炸了],并且数据也非常水…忽视第三题的锅的话的确可以这么说.但是T3数据出锅就是你的错了 ...
- 2019.8.5 NOIP模拟测试13 反思总结【已更新完毕】
还没改完题,先留个坑. 放一下AC了的代码,其他东西之后说… 改完了 快下课了先扔代码 跑了跑了 思路慢慢写 来补完了[x 刚刚才发现自己打错了标题 这次考试挺爆炸的XD除了T3老老实实打暴力拿了52 ...
随机推荐
- 关于N个小球放M个盒子解答
以下是关于关于N个小球放M个盒子的几种情况的解答,蛮详细的(来自博友的) 求精:关于N个小球放M个盒子解答 - chensmiles的日志 - 网易博客http://chensmiles.blog. ...
- springMVC项目创建及导入包项
springMVC项目创建及导入包项 - zhangzhetaojj的博客 - CSDN博客https://blog.csdn.net/zhangzhetaojj/article/details/50 ...
- 当EntityFramework爱上AutoMapper
有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易,相处不易. 在DDD(领域驱动设计)中,使用AutoMapp ...
- 深入浅出 Java Concurrency (38): 并发总结 part 2 常见的并发场景[转]
常见的并发场景 线程池 并发最常见用于线程池,显然使用线程池可以有效的提高吞吐量. 最常见.比较复杂一个场景是Web容器的线程池.Web容器使用线程池同步或者异步处理HTTP请求,同时这也可以有效的复 ...
- ASP.NET MVC生命周期与管道模型
先来熟悉下asp.net请求管道 1.当客户端发送http://localhost:80/home/index请求时 2.首先到达服务端的内核模块HTTP.SYS(它监听80端口),通过访问注册表 ...
- iOS开发系列-SQLite
概述 SQLite3是一款轻型的嵌入式数据库.它占用资源非常低,在嵌入式设备中,可能只需要几百K的内存就够了.它的处理速度比Mysql.PostgreSQL这两款著名的数据库速度还快. 数据库简介 常 ...
- Redis Set ZSet类型的学习
- lc6 ZigZag Conversion
lc6 ZigZag Conversion 分成两步, 第一步垂直向下, 1 1 1 1 第二步倾斜向上 1 1 1 1 1 1 1 用nRows个StringBuilder 然后将他们合并即可 cl ...
- 第五章 Odoo 12开发之导入、导出以及模块数据
大多数Odoo 模块的定义,如用户界面和安全规则,实际是存储在对应数据表中的数据记录.模块中的 XML 和 CSV 文件不是 Odoo 应用运行时使用,而是载入数据表的手段.正是因为这个原因,Odoo ...
- Server 主机屋云服务器 宝塔面板 部署nginx反向代理的vue项目
图文记录云服务器上部署需要nginx反向代理的vue项目: 一.先登录并购买云服务器,根据自己需求购买,此处不详细介绍: 二.登录后如下图,点击进入云服务器界面: 三.在云服务器界面点击管理,进入管理 ...