D1T1.铺地毯

for循环

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct hp{
int a,b,g,k;
}map[];
int main()
{
int n,i,x,y;
cin>>n;
for(i=;i<=n;i++)
cin>>map[i].a>>map[i].b>>map[i].g>>map[i].k;
cin>>x>>y;
for(int i=n;i>=;i--)
{
if(map[i].a<=x&&map[i].a+map[i].g>=x&&map[i].b<=y&&map[i].b+map[i].k>=y)
{cout<<i<<endl;return ;}
}
cout<<"-1"<<endl;
return ;
}

D1T2.选择客栈

这道题O(kn)算法很简单啊,我来讲讲O(n)的算法吧

a[c]表示记录到第i个客栈为止色调为c的客栈的总数

b[c]表示记录到离当前客栈i最近的消费水平不高于p的客栈为止色调为c的客栈的数量

s[c]记录到当前客栈i为止,最后一个色调为c的客栈的编号

f记录距离客栈i最近的消费水平不超过p的客栈的编号

每读入一个客栈的色调c和最低消费v,我们首先来判断v是否超过了p,如果v没有超过p的话,我们让f=i,即先更新f。

每读入一组数据c和v,我们就应该更新a[c]和s[c],但是在这一步之前,我们要做如下操作:

不管当前客栈i的消费水平如何,我们来比较f和最后一个色调为c的客栈的编号s[c]的大小关系,

由于我们还没有更新s[c],所以这次比较不包含当前客栈i;

对于当前客栈i的色调c来说,如果该色调是在编号为f的客栈之后第一次出现,则必有f>=s[c],那么a[c]里面记录的必然是在f客栈之前(包括f)色调为c的客栈的数量,这时我们让b[c]=a[c],

如果色调c在客栈f之后出现的次数多于1次,那么我们必然已经更新过s[c],那么必然有s[c]>f,这时我们不做任何操作,则b[c]内保存的依然是在客栈f之前(包括f)色调为c的客栈的数量。

在这里,f发生变化与否,对结果是没有影响的,因为即便在这一步之前f发生了变化,如果某个色调c一直没有出现的话,那对结果没有任何影响,

而一旦某个色调在f变化之后第一次出现,必然有f>=s[c],这时必然要更新b[c],那么b[c]必然在这里就会更新成为我们后面计算需要的正确的值,而且在f再次变化之前,b[c]将保持不变。

#include<cstdio>
int a[],b[],s[],f=,n,k,p,c,v,ans=;
int main()
{
scanf("%d%d%d",&n,&k,&p);
for(int i=;i<=n;i++)
{
scanf("%d%d",&c,&v);
if(v<=p)f=i;
if(f>=s[c])b[c]=a[c];
ans+=b[c];a[c]++;s[c]=i;
}
printf("%d",ans);
return ;
}

D1T3 Mayan游戏

搜索+剪枝

1.因为1优先于-1,所以如果一个方块左边也有方块,那么不用搜索这个状态

2.直接从地图的左下角按从下到上,从左到右的顺序搜索

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
bool ret=;
int mp[][],n,ansx[],ansy[],ansg[];
void diao()
{
int w[];memset(w,,sizeof(w));
for(int j=;j<=;j++)
for(int i=;i>=;i--)
{
if(!mp[i][j]){w[j]=i;break;}
}
for(int i=;i>=;i--)
for(int j=;j<=;j++)
{
if(mp[i][j])
{
if(i>w[j])continue;
mp[w[j]][j]=mp[i][j];mp[i][j]=;w[j]--;
}
}
}
bool xiao()
{
int _mp[][];bool ok=;
for(int i=;i<=;i++)for(int j=;j<=;j++)_mp[i][j]=mp[i][j];
for(int i=;i<=;i++)
{
int j=;
while(j<=)
{
if(_mp[i][j]==){j++;continue;}int stop;
for(stop=j+;stop<=;stop++)if(_mp[i][stop]!=_mp[i][stop-])break;
if(stop-j>=){for(;j<stop;j++)mp[i][j]=;ok=;}
else j=stop;
}
}
for(int j=;j<=;j++)
{
int i=;
while(i<=)
{
if(_mp[i][j]==){i++;continue;}int stop;
for(stop=i+;stop<=;stop++)if(_mp[stop][j]!=_mp[stop-][j])break;
if(stop-i>=){for(;i<stop;i++)mp[i][j]=;ok=;}
else i=stop;
}
}
return ok;
}
void dfs(int t)
{
if(ret)return;
int _mp[][];
if(t>n)
{
bool ok=;
for(int i=;i<=;i++)
for(int j=;j<=;j++)if(mp[i][j])ok=;
if(!ok)
{
for(int i=;i<=n;i++)printf("%d %d %d\n",ansx[i],ansy[i],ansg[i]);
ret=;
return;
}
return;
}
int color[];memset(color,,sizeof(color));
bool ok=;
for(int i=;i<=;i++)for(int j=;j<=;j++)
{
_mp[i][j]=mp[i][j];color[mp[i][j]]++;if(mp[i][j])ok=;
}
if(!ok)return;
for(int i=;i<=;i++)if(color[i]>&&color[i]<)return;
for(int j=;j<=;j++)
for(int i=;i>=;i--)
{
if(mp[i][j]==)continue;
if(j!=)
{
swap(mp[i][j],mp[i][j+]);
do{
diao();
}while(xiao());
ansx[t]=j-;ansy[t]=-i;ansg[t]=;dfs(t+);
for(int i=;i<=;i++)for(int j=;j<=;j++)mp[i][j]=_mp[i][j];
}
if(j!=)
{
if(mp[i][j-]!=)continue;
swap(mp[i][j],mp[i][j-]);
do{
diao();
}while(xiao());
ansx[t]=j-;ansy[t]=-i;ansg[t]=-;dfs(t+);
for(int i=;i<=;i++)for(int j=;j<=;j++)mp[i][j]=_mp[i][j];
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
scanf("%d",&mp[-j][i]);if(!mp[-j][i])break;
}
dfs();
if(!ret)printf("-1");
return ;
}

D2T1 计算系数

杨辉三角

#include<iostream>
using namespace std;
int dp[][];const int mod=;
int main()
{
int a,b,k,n,m;scanf("%d%d%d%d%d",&a,&b,&k,&n,&m);
for(int i=;i<=k+;i++)dp[i][i]=,dp[i][]=;
for(int i=;i<=k+;i++)
for(int j=;j<i;j++)dp[i][j]=(dp[i-][j]+dp[i-][j-])%mod;
long long ans=dp[k+][m+];
for(int i=;i<=n;i++)ans=(ans*a)%mod;
for(int i=;i<=m;i++)ans=(ans*b)%mod;
cout<<ans;
return ;
}

D2T2 聪明的质检员

首先分析公式计算,容易发现sigma ci会随着 m 的递增单调递减。
因此答案满足了单调性,我们考虑二分答案 m,然后对于每次二分出来的答案check 的话,时间复杂度太高。

我们可以发现,可以使用前缀和来 O(1)回答区间查询,对于每个二分出来的 m,先花 O(n)的时间按题意做一下前缀和,然后再 O(q)计算一下 sigma,

这样的话就可以把每次二分完的 O(nq)优化到 O(n+q),总时间复杂度为O((n+q)log2S)

#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int w[],v[],l[],r[],sw[],b[],c[];
int main()
{
int n,m;long long s;scanf("%d%d%lld",&n,&m,&s);
for(int i=;i<=n;i++){scanf("%d%d",&w[i],&v[i]);sw[i]=w[i];}
for(int i=;i<=m;i++)scanf("%d%d",&l[i],&r[i]);
sort(sw+,sw+n+);
long long ans=999999999999LL;int _l=,_r=n+;
while(_l<_r)
{
int mid1=(_l+_r)/;
int mid=sw[mid1];
b[]=;c[]=;
for(int i=;i<=n;i++)
{
int g=v[i];c[i]=c[i-];
if(w[i]<mid)g=;
else c[i]++;
b[i]=b[i-]+g;
}
long long x=;
for(int i=;i<=m;i++)x+=(b[r[i]]-b[l[i]-])*(c[r[i]]-c[l[i]-]);
if(x<s)_r=mid1;
else _l=mid1+;
ans=min(ans,abs(x-s));
}
printf("%lld",ans);
return ;
}

D2T3 观光公交

sum[i]:在前i站下车的人的总数;las[i]:最晚的一个人的到达i站的时间;get[i]最早的到达i站时间。

那么,题目所求的问题就是∑(get[b[i]]-t[i])。

可以转化为:∑(get[b[i]])-∑(t[i])。而∑(t[i])是定值,于是就是要使∑(get[b[i]])最小。

至于get[i],它取决于上一站的到站时间和最晚的一个人,get[i]=max(las[i-1],get[i-1])+d[i-1]。

容易想到,如果一个d[i]减小了,那么它肯定会影响到后面的一段连续的get[i]。

具体地来说,如果get[i]>las[i],也就是车的最早到达时间要晚于最慢的人的到达时间,那么前面如果用了加速器,那么就能使get[i]减小,否则就不能造成影响。

我们开一个数组g[i]表示如果d[i]减小,那么最多影响到后面的哪个站。很明显,随着d[i]的减小,g[i]是要变的。

g[i]=g[i+1](get[i+1]>las[i+1],后一个站的出发时间由到达时间决定)   或   i+1(get[i+1]<=las[i+1],后一个站的出发时间由最晚到达的人决定)。

要使加速器的效果最大,那么就要使这个加速器的作用影响到最多的人,于是每次找sum[g[i]]-sum[i]最大的一个d[i]加速(d[i]>0)。重复k次即可。

每一个加速器互不影响,所以不存在后效性,局部最优即是全局最优。

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,k,sum[],las[],get[],g[],ans=;
int d[],a[],b[],t[];
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<n;i++)scanf("%d",&d[i]);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&t[i],&a[i],&b[i]);
las[a[i]]=max(las[a[i]],t[i]);sum[b[i]]++;
}
for(int i=;i<=n;i++)sum[i]+=sum[i-];
for(int i=;i<=n;i++)
{
get[i]=max(get[i-],las[i-])+d[i-];
}
g[n]=n;
for(int i=n-;i>=;i--)
{
if(get[i+]>las[i+])g[i]=g[i+];
else g[i]=i+;
}
for(int i=;i<=m;i++)ans+=get[b[i]]-t[i];
while(k)
{
int rs=,l,r;
for(int i=;i<n;i++)
{
if(sum[g[i]]-sum[i]>rs&&d[i])
{
rs=sum[g[i]]-sum[i];l=i;r=g[i];
}
}
d[l]--;ans-=rs;
for(int i=l;i<=r;i++)
{
get[i]=max(get[i-],las[i-])+d[i-];
}
if(r==n)r--;g[n]=n;
for(int i=r;i>=l;i--)
{
if(get[i+]>las[i+])g[i]=g[i+];
else g[i]=i+;
}
k--;
}
printf("%d",ans);
return ;
}

NOIP2011提高组的更多相关文章

  1. luogu1003铺地毯[noip2011 提高组 Day1 T1]

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  2. [NOIP2011] 提高组 洛谷P1312 Mayan游戏

    题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定 ...

  3. [NOIP2011] 提高组 洛谷P1315 观光公交

    题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号景点,随后依次前往 2 ...

  4. [NOIP2011] 提高组 洛谷P1003 铺地毯

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  5. NOIP2011(提高组)DAY2---观光公交(vijosP1741)

    描述 风景迷人的小城Y市,拥有n个美丽的景点.由于慕名而来的游客越来越多,Y市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0分钟出现在1号景点,随后依次前往2.3.4……n号景 ...

  6. 洛谷-铺地毯-NOIP2011提高组复赛

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  7. 刷题总结——mayan游戏(NOIP2011提高组day2T3)

    题目: 题目背景 NOIP2011提高组 DAY1 试题. 题目描述 Mayan puzzle 是最近流行起来的一个游戏.游戏界面是一个 7 行 5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即 ...

  8. 洛谷P1003 铺地毯 noip2011提高组day1T1

    洛谷P1003 铺地毯 noip2011提高组day1T1 洛谷原题 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n ...

  9. [Luogu1313][NOIP2011提高组]计算系数

    题目描述 给定一个多项式 (by+ax)k(by+ax)^k(by+ax)k ,请求出多项式展开后 xn×ymx^n \times y^mxn×ym 项的系数. 输入输出格式 输入格式: 共一行,包含 ...

  10. Noip2011 提高组 Day1 T1 铺地毯 + Day2 T1 计算系数

    Day1 T1 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小 ...

随机推荐

  1. 2 http协议

    http协议简介: HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文 ...

  2. Redis数据更新

    技术交流群: 233513714

  3. Kafka写入流程和副本策略

    Kafka写入流程: 1.producer 先从 zookeeper 的 "/brokers/.../state" 节点找到该 partition 的 leader 2. prod ...

  4. springboot 入门2 开发环境与生产环境采用不同配置问题

    目开发中我们通常有两套配置信息  分别配置了我们的数据源信息等? 那么我们要如何不通过修改配置文件大量配置来实现简单的修改与配置来实现相关配置加载功能 首先springboot 有一个核心的配置文件a ...

  5. Oracle 11g数据库安装与卸载的方法图解(windows)

    一.Oracle 11g安装 安装之前要先确定自己的电脑配置,以windows为例,如果是win7以下系统如xp等,可以选择Oracle 10g.因为10g的程序文件只有200多兆,而11g及达到了2 ...

  6. 平时收集的一些有关UED的团队和个人博客

    平时收集的一些有关UED的团队和个人博客 前端团队阿里巴巴 UED -- 我们设计的界面,并没有几十亿的流量,但每天来自上百个国家的百万商人在使用着.阿里巴巴中国站UED -- 阿里巴巴中国站UED成 ...

  7. 《Cracking the Coding Interview》——第13章:C和C++——题目8

    2014-04-25 20:27 题目:实现一个能够通过引用计数来实现自动回收数据的智能指针,用C++,不是java. 解法:这题真心牛,我的第一反应是发呆,因为对引用计数的了解仅限于这个名词,完全没 ...

  8. ubuntu下eclipse 安装记录

    基本是参考:http://www.metsky.com/archives/611.html 完成. 中间遇到小问题,在此记录下,方便遇到同样问题的难友. 先说下快速打开命令行快捷键:Ctrl+Alt+ ...

  9. JMeter学习笔记(十一) 关于 CSV Data Set Config 的 Sharing mode 对取值的影响

    关于 CSV Data Set Config 的一些介绍之前已经梳理过了,可以参考: https://www.cnblogs.com/xiaoyu2018/p/10184127.html . 今天主要 ...

  10. Java基础-6流程控制

    一).选择控制: 选择控制分为两种:if...else...和switch 单分支结构:这是最简单的一种选择结构,它只是简单的判断某个条件是否成立,如果成立就执行一段代码,语句形式为: if(条件表达 ...