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 ...
随机推荐
- 「题解」:[AHOI2012] 树屋阶梯
A掉了第一道题然后就去肝第四题,被路过的Larry大神看到了. L:你怎么还没过掉第三题? 我:…… L:快我帮你过掉! 他拉下来我第一题的码,手改了两个参数,半分钟后:AC …… 然后我就理所当然的 ...
- LUOGU P2949 [USACO09OPEN]工作调度Work Scheduling (贪心)
解题思路 明明一道比较简单的贪心结果挂了好几次23333,就是按照时间排序,然后拿一个小根堆维护放进去的,如果时间允许就入队并且记录答案.如果不允许就从堆里拿一个最小的比较. #include< ...
- LUOGU P1291 [SHOI2002]百事世界杯之旅 (期望dp)
传送门 解题思路 期望$dp$.因为这个是期望步数,所以要倒着推.那么这道题就变得一脸可做了,设$f[i]$表示还有$i$张牌没有收集的期望,那么考虑再抽一张,有$(n-i)/n$的概率抽到抽过的牌, ...
- C++编程规范和编译过程详解
前言:因为c++基础打得不牢,所以准备花点时间再学一下c++的基础知识,主要是看网易云课堂里面的免费课程,把一些知识点做个笔记记下来. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- php完整表单实例
PHP - 在表单中确保输入值 在用户点击提交按钮后,为确保字段值是否输入正确,我们在HTML的input元素中插添加PHP脚本, 各字段名为: name, email, 和 website. 在评论 ...
- 深入浅出 Java Concurrency (24): 并发容器 part 9 双向队列集合 Deque[转]
有一段时间没有更新了.接着上节继续吧. Queue除了前面介绍的实现外,还有一种双向的Queue实现Deque.这种队列允许在队列头和尾部进行入队出队操作,因此在功能上比Queue显然要更复杂.下图描 ...
- java代码优化写法1(转摘)
源文地址:https://blog.csdn.net/qq_15766297/article/details/70503222 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修 ...
- ElasticSearch入门之彼行我释(四)
散仙在上篇文章中,介绍了关于ElasticSearch基本的增删改查的基本粒子,本篇呢,我们来学下稍微高级一点的知识: (1)如何在ElasticSearch中批量提交索引 ? (2)如何使用高级查询 ...
- Windows API 第二篇 SHGetSpecialFolderPath
BOOL SHGetSpecialFolderPath( HWND hwndOwner, LPTSTR lpszPath, ...
- NOI2018 Day1 归程(return)
第一次参加NOI,当然,我没去现场做,只是在网络同步赛做了而已. 那网站,特别特别卡啊-- 最后只交了第一题,原本认为能AC,但是因为某些原因只有50分. 我这可怜的第一次啊-- 题目 题目点此处下载 ...