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. B1086 就不告诉你 (15分)

    B1086 就不告诉你 (15分) 做作业的时候,邻座的小盆友问你:"五乘以七等于多少?"你应该不失礼貌地围笑着告诉他:"五十三."本题就要求你,对任何一对给定 ...

  2. 9.2python操作redis

    Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...

  3. 15.3,redis持久化RDB与AOF

    redis持久化 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失. RDB持久化 ...

  4. MyEclipse - 问题集 - maven update project 后,项目jdk的版本变化

    解决方法: 进入maven安装根目录,conf/settings.xml <profiles> <profile> <id>jdk-1.7</id> & ...

  5. MySQL添加和删除字段

    查询表的字段类型: mysql> desc t_template_title; +----------------+--------------+------+-----+---------+- ...

  6. Flash文件在asp页面无法播放,网页上面的Flash文件在火狐浏览器不播放

    第一个问题:Flash文件放到asp页面以后无法播放. 解决方法:用浏览器打开页面->F12,选择Network,如下图: 然后刷新页面,如下图: 点击左侧状态是404的文件,如图: 可以发现F ...

  7. 编译gearman提示缺少boost

    编译german时提示缺少boost: checking for boostlib >= 1.39... configure: We could not detect the boost lib ...

  8. php静态文件返回304

    有时一些静态文件(如图片)会由php输出,会发现请求都是200,静态文件每次都去服务器上请求太浪费资源了,这时如何让浏览器缓存图片呢?就需要我们在php中输出304了. 我们可以利用php中的 HTT ...

  9. 孤荷凌寒自学python第二十三天python类的封装

    孤荷凌寒自学python第二十三天python类的封装 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.从怎么样访问类的内部代码块中定义的私有属性说起 类中定义的私有属性和私有方法是无法被 ...

  10. ironic的自动化脚本

    # -*- coding:utf-8 -*- import json import subprocess import os import time import random trunk_start ...