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. 交互式的Bourne shell

    简介 当以交互的方式使用命令行时,shell有一些特殊的内置变量,这些变量中包含一系列选项.如果在选项中包含字母i,则表示shell以交互方式运行. # case "$-" in ...

  2. [BZOJ3714]Kuglarz(最小生成树)

    Description 魔术师的桌子上有n个杯子排成一行,编号为1,2,-,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品.花费\(C_{i,j}\)元,魔术师就会告诉 ...

  3. Wireshark 的使用

    Wireshark 默认无法查看 https, 需要设置一下 新建环境变量 SSLKEYLOGFILE, 值为一个想要保存 sshKey 的文件, 如新建一个空文件 D:\AppData\SshKey ...

  4. startActivityForResult 请求码不正确

    今天遇到一个坑,就是 startActivityForResult 接收不到正确的请求码. 比如,我startActivityForResult的时候,设置的请求码是4,但是接收到的时候是100032 ...

  5. C#冒泡算法复习

    C#冒泡算法复习 冒泡算法的意思:每一趟找到一个最小或最大的数放到最后面,比较总数的n-1次(因为比较是2个双双比较的) 第一层循环表示进行比较的次数,总共要比较(数的)-1次 (因为比较是2个双双比 ...

  6. CentOS 单用户模式:修改Root密码和grub加密[转]

    原文出处: http://zhengdl126.iteye.com/blog/430268 Linux 系统处于正常状态时,服务器主机开机(或重新启动)后,能够由系统引导器程序自动引导 Linux 系 ...

  7. DOS程序员手册(十三)

    744页 在DPMI 1.0下,系统会修改并重新装载所有含选择符的段寄存器,并且将所有 含有要释放的选择符的寄存器清空为0. 客户程序绝不能修改或释放该功能分配的任何描述符.Int 31h.功能010 ...

  8. jmeter 运行脚本报错 java.net.BindException: Address already in use

    在win下跑jmeter时,在聚合报告中出现错误.打开日志文件(前提是将日志写入了指定文件) 发现报错的原因为:java.net.BindException: Address already in u ...

  9. Kotlin的数据类:节省很多行代码(KAD 10)

    作者:Antonio Leiva 时间:Jan 25, 2017 原文链接:https://antonioleiva.com/data-classes-kotlin/ 在前面的文章中,我们已经见到了类 ...

  10. eclipse集成python(Pydev插件安装)

    1.下载PyDev的压缩包,解压后会有features和plugins两个文件夹,将两个文件夹的内容拷贝到eclipse对应的文件夹中,重新启动eclipse 2.配置python 2.1打开ecli ...