NOIP模拟测试14「旋转子段·走格子·柱状图」
旋转子段
连60分都没想,考试一直肝t3,t2,没想到t1最简单
我一直以为t1很难,看了题解发现也就那样
题解
性质1
一个包含a[i]旋转区间值域范围最多为min(a[i],i)----max(a[i],i)
感性理解
举个例子,例如3 7 1 4 5 6 2
这个子段包含a[2]的最大为值域范围2----7
具体证明我不会
性质2
翻转后满足固定点对的点满足
a[i]+i==a[j]+j
证明
因为翻转之前a[i]==j&&a[j]==i才满足翻转之后都构成点对
移项得到a[i]+i==a[j]+j
有了这两条性质我们可以得到一个$n^2$算法
for(ll i=1;i<=n;i++){tot=0;for(ll j=min(i,a[i]);j<=max(i,a[i]);j++)if(a[j]+j==a[i]+i)tot++; }
得到tot最大值输出即可
70分代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1010101 ll f[A],a[A],sum[A]; ll n,ans=-1,tot=0; vector<ll>too[501010]; int main(){scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&a[i]);sum[i]=sum[i-1];if(a[i]==i) sum[i]++;}for(ll i=1;i<=n;i++){tot=0;for(ll j=min(i,a[i]);j<=max(i,a[i]);j++){if(a[j]+j==a[i]+i){tot++;}} // printf("n=%lld max=%lld min=%lld i=%lld tot=%lld\n",n,max(i,a[i]),min(i,a[i]),i,tot);ans=max(tot+sum[n]-sum[max(i,a[i])]+sum[min(i,a[i])-1],ans);}printf("%lld\n",ans); }
View Code
100分
莫队维护一下询问,需要卡常,卡常到自闭,fh卡常大师
分块0.53最优
#include<bits/stdc++.h> using namespace std; #define ll int const int A=1010101,L=1<<20|1; #define getchar() ((S==T&&(T=(S=buf)+fread(buf,1,L,stdin),S==T))?EOF:*S++) ll f[A],a[A],sum[A],tong[A],belong[A]; ll n,ans=-1,l=1,r=0,ou=0,block; char buf[L],*S,*T; struct moo{ll zhong,r,l,a;friend bool operator < (moo a,moo b){return ((belong[a.l]^belong[b.l]))?a.l<b.l:((belong[a.l]&1)?a.r<b.r:a.r>b.r);} }mo[A]; inline ll read(){ll x=0;char c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();return x; } int main(){n=read();block=pow(n,0.53);for(register ll i=1;i<=n;i++){a[i]=read();sum[i]=sum[i-1];if(!(a[i]^i)) sum[i]++;belong[i]=(i-1)/block+1;}for(register ll i=1;i<=n;i++){mo[i].zhong=i;mo[i].r=max(i,a[i]);mo[i].l=min(i,a[i]);mo[i].a=a[i];}sort(mo+1,mo+n+1);for(register ll i=1;i<=n;i++){while(l>mo[i].l) tong[l-1+a[l-1]]++,l--;while(l<mo[i].l) tong[l+a[l]]--,l++;while(r>mo[i].r) tong[r+a[r]]--,r--;while(r<mo[i].r) tong[r+1+a[r+1]]++,r++;ans=max(tong[mo[i].zhong+mo[i].a]+sum[n]-sum[mo[i].r]+sum[mo[i].l-1],ans);}printf("%d",ans); }
View Code
走格子
显然贪心有门走门不对一个稍简单的数据就可以卡掉你
7 8 ######## ##.F#..# #...C..# ##..#..# ##.....# #..#...# ########
那怎么办,只能走八个方向爆搜吗?
显然可以最短路!
从每个墙开始搜直接得到每个点到墙最短距离,然后每两相邻点之间建边,点墙之间建边
例如 (墙)
|
50
|
(墙)-----21------Q-------------500000000-------(墙)
|
|
600
|
(墙)
我们只需要将Q与四个墙方向边权都设置为21即可.(例如可以在2打传送门 然后在4打传送门从2传送到4,那么所有最小代价都为21)
很简单对不对,直接跑最短路就行了
保证最短路会松弛掉一些不可行解
例如
(墙)
|
50
(墙)|
(墙)------21--Q-------500000--(墙)
|
50
|
(终点)
向上走一步再打传送门会松弛掉21这条边
代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define A 5010101 #define py printf("toot\n") #define fr first #define se second #define mp(x,y) make_pair(x,y) ll zh[610][610],top[610][610],low[610][610],zuo[610][610],you[610][610],bs[610][610],head[A],nxt[A],ver[A],edg[A],dis[A]; const ll nowx[5]={0,0,0,1,-1}; const ll nowy[5]={0,1,-1,0,0}; bool vis[A]; ll n,m,zhongx,zhongy,qix,qiy,ttt=0,tot=0; deque<pair<ll,ll> >q,toot; char s[610][610]; ll id(ll i,ll j){return (i-1)*m+j; } void add(ll x,ll y,ll z){nxt[++tot]=head[x],head[x]=tot,ver[tot]=y,edg[tot]=z;return ; } void ins(ll x,ll y,ll d){if(!bs[x][y]&&s[x][y]=='.'){bs[x][y]=d;q.push_back(mp(x,y));} } void bfs(){while(!q.empty()){ll kx=q.front().fr,ky=q.front().se;q.pop_front(); // py;for(ll i=1;i<=4;i++){ins(kx+nowx[i],ky+nowy[i],bs[kx][ky]+1);}} } void init(){for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++){if(s[i][j]=='#') continue;if(s[i][j-1]=='#') zuo[i][j]=id(i,j);else zuo[i][j]=zuo[i][j-1];if(s[i-1][j]=='#') top[i][j]=id(i,j);else top[i][j]=top[i-1][j];}for(ll i=n;i>=1;i--)for(ll j=m;j>=1;j--){if(s[i][j]=='#') continue;if(s[i][j+1]=='#') you[i][j]=id(i,j);else you[i][j]=you[i][j+1];if(s[i+1][j]=='#') low[i][j]=id(i,j);else low[i][j]=low[i+1][j];} } void addb(){for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++){if(s[i][j]=='#') continue;ll d=id(i,j);if(s[i+1][j]=='.') add(d,id(i+1,j),1),add(id(i+1,j),d,1);if(s[i][j+1]=='.') add(d,id(i,j+1),1),add(id(i,j+1),d,1);if(zuo[i][j]!=d)add(d,zuo[i][j],bs[i][j]);if(you[i][j]!=d)add(d,you[i][j],bs[i][j]);if(top[i][j]!=d)add(d,top[i][j],bs[i][j]);if(low[i][j]!=d)add(d,low[i][j],bs[i][j]);} } void spfa(ll o){vis[o]=1;memset(dis,0x7f,sizeof(dis));dis[o]=0;deque<ll> toot;toot.push_back(o);while(!toot.empty()){ll x=toot.front();toot.pop_front();for(ll i=head[x];i;i=nxt[i]){ll y=ver[i];if(dis[y]>dis[x]+edg[i]){dis[y]=dis[x]+edg[i];if(!vis[y]){vis[y]=1;toot.push_back(y);}}}vis[x]=0;} } int main(){scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++){scanf("%s",s[i]+1);for(ll j=1;j<=m;j++){if(s[i][j]=='#'){q.push_back(mp(i,j));}else if(s[i][j]=='C'){s[i][j]='.';qix=i;qiy=j;}if(s[i][j]=='F'){s[i][j]='.';zhongx=i;zhongy=j;}}}bfs(),init(),addb(),spfa(id(qix,qiy));if(dis[id(zhongx,zhongy)]>=1202134)printf("no\n");else printf("%lld\n",dis[id(zhongx,zhongy)]); }
View Code
柱状图
模拟退火板子题,非常板子
模拟退火最吼了
即使是板子我也要说说
首先关于
nth_element(s+1,s+mid,s+n+1);
为什么要求出中位数,
前置知识
坐标轴上有很多点,点与点之间有一个距离,你将所有点移到同一个点最小花费
显然是移到中位数的点
那么应用到这个题呢?
你可以将题目要求转化,首先全部移到同一水平线上,然后再加出值
比它高的降低,比它矮的升高,换成坐标轴我们就用到了中位数
然后
if(tmpans<nowans||exp(-D/T)*RAND_MAX>rand())
为什么是
exp(-D/T)*RAND_MAX>rand()
不是
exp(D/T)*RAND_MAX>rand()
问的好啊!
首先我们如果当前解优那么你会通过tmpans<nowans跳过
然后如果当前解不优D一定是负的,如果D为负的那么D越小-D越大.D小代表当前解非常差,让它变成其他解概率更大
#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1010101 const double eps=1e-5; const double delta=0.98; const double fj=1; ll n,ans=0x7ffffffffffffff; ll s[A],h[A]; ll check(ll pos){for(ll j=1;j<=n;j++)s[j]=h[j]+abs(pos-j);ll mid=n+1>>1;nth_element(s+1,s+mid,s+n+1);ll val=s[mid];ll tot=0;if(val<max(pos,n-pos+1))val=max(pos,n-pos+1);for(ll i=1;i<=n;i++)tot+=abs(s[i]-val);return tot; } int main(){srand(time(0));scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&h[i]);}double T=1000;ll now=(n+1)>>1;ll nowans=check(now);while(T>eps){ll tmp=now+(2ll*rand()-RAND_MAX)*T*0.000001;tmp=(tmp%n+n-1)%n+1;ll tmpans=check(tmp),D=tmpans-nowans;if(tmpans<nowans||exp(-D/T)*RAND_MAX>rand())nowans=tmpans,now=tmp;if(tmpans<ans) ans=tmpans;T*=delta;}printf("%lld\n",ans); }
View Code
转载于:https://www.cnblogs.com/znsbc-13/p/11319578.html
NOIP模拟测试14「旋转子段·走格子·柱状图」相关推荐
- NOIP模拟测试13「矩阵游戏·跳房子·优美序列」
矩阵游戏 考试时思路一度和正解一样,考试到最后还是打了80分思路,结果80分打炸了只得了40分暴力分 题解 算出来第一列的总值,每次通过加每两列之间的差值得出下一列的总值 算第一列我们只需要让当前点* ...
- NOIP模拟测试5「星际旅行·砍树·超级树」
星际旅行 0分 瞬间爆炸. 考试的时候觉得这个题怎么这么难, 打个dp,可以被儿子贡献,可以被父亲贡献,还有自环,叶子节点连边可以贡献,非叶子也可以贡献,自环可以跑一回,自环可以跑两回, 关键是同一子 ...
- NOIP模拟测试19「count·dinner·chess」
反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...
- NOIP模拟测试18「引子·可爱宝贝精灵·相互再归的鹅妈妈」
待补 引子 题解 大模拟,注意细节 代码1 #include<bits/stdc++.h> using namespace std; int n,m;char a[1005][1005]; ...
- NOIP模拟测试15「建造城市city(插板法)·轰炸·石头剪刀布」
建造城市 题解 先思考一个简单问题 10个$toot$ 放进5间房屋,每个房屋至少有1个$toot$,方案数 思考:插板法,$10$个$toot$有$9$个缝隙,$5$间房屋转化为$4$个挡板,放在t ...
- NOIP模拟测试30「return·one·magic」
magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i=1}^{i<=N} [gcd(i,N)==1] C_{G ...
- NOIP模拟测试29「爬山·学数数·七十和十七」
爬山题解不想写了 学数数 离散化然后找到以每一个值为最大值的连续子段有多少个,然后开个桶维护 那么怎么找以每一个值为最大值的连续子段个数 方法1(我的极笨的方法) 考试时我的丑陋思路, 定义极左值为左 ...
- NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」...
题目比较神仙,注意是题目神仙 贪婪暗示贪心,堆积暗示堆优化$\%\%\%\%\%\%\%$ 两个乱搞$+$一个堆优化$dp$ 嚎叫响彻在贪婪的机房 题解 对于一个序列来说只要他们差的$gcd$不为$1 ...
- NOIP模拟测试25「字符串·乌鸦喝水·所陀门王的宝藏(陀螺王)」
字符串 题解 没看出catalan怎么办 dp打表啊! 考虑大力dp拿到30分好成绩!顺便收获一张表 打表发现$C_{n+m}^{m}-C_{n+m}^{m-1}$ 仔细观察然后发现其实就是之前的网格 ...
最新文章
- 获取本机MSSQL保存凭证
- 获取不到app.config里面的数据库连接字符串的解决方法
- JDK ShutdownHook - 优雅地停止服务
- c语言使用正则,C语言中使用正则表达式
- 碧雪情天服务器地址源如何修改,稀有游戏《碧雪情天online》网络版王者归来一键服务端+客户端 支持转生系统和新图...
- vue-resource插件使用
- thinkphp5 return 返回空_杨丞琳演唱会意外踩空,从两层楼高的舞台掉落,李荣浩心疼发文...
- Kubernetes 是什么?为什么也称为 K8S?| 科普
- 深度学习模型迁移到VisualC++ demo
- matlab 特征选择算法,特征选择、特征提取matlab算法实现(模式识别)
- js实现图片加载中效果 loading
- bat 注释,echo off 和 rem 和 :
- 人脸识别活体检测测试案例
- java验证用户名和密码_java验证用户名和密码详解
- Sql Server数据库中查询操作时“对象名无效”解决方法
- 微创新:粉丝电子商务及微博的9种盈利模式
- 看不到工作组的其他计算机_就这一次,从现实世界的角度去理解计算机领域的知识(给新手)...
- define的函数用法
- vs2017下libcef配置
- 大数据基础篇~JavaSE第三章
热门文章
- nosql简答什么是最终一致性_NoSql的三大基石:CAP理论BASE最终一致性
- Maven的单元测试没有执行的问题
- Linux 命令之 who -- 打印当前登录用户/显示目前登入系统的用户信息。
- Linux 命令之 pwconv -- 开启用户的投影密码
- php 获取请求设备,php – 如何获取设备令牌
- 股票实例_注意了!手中的股票涨停,但是却封不住反复打开,说明了什么?看懂持股不慌...
- mvc @html.editorfor,在MVC中,@Html.EditorFor(m = ( )_CSharp_开发99编程知识库
- python收集数据程序_用Python挖掘Twitter数据:数据采集
- Leetcode 19. 删除链表的倒数第N个节点
- 【开源项目】基于FFmpeg的封装格式转换