这套题思考的难度比较大,应该说是有四题基础题,一题比较复杂的搜索加模拟,还有一题需要深度思考一下。自己的代码漏洞还是很大,而且思考的时候会遗漏一些情况,这些错误都是致命的,去年Noip的惨败也证实了这一点,许多时候,我并没有败在算法上,而是细节与心态上。记住犯过的错误,尽力不在同一个地方摔倒,那么才可能不断进步,否则一直都在原地踏步。

DAY1 》

T1:铺地毯

  枚举然后判断,就是考验基础的代码能力

#include <cstdio>
int x,y,ans,n,h[10005],t[10005],l[10005],r[10005];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d%d%d",&h[i],&l[i],&t[i],&r[i]);
ans=-1; scanf("%d%d",&x,&y);
for(int i=1;i<=n;i++)if(h[i]<=x&&(x<=h[i]+t[i])&&l[i]<=y&&(y<=r[i]+l[i]))ans=i;
printf("%d\n",ans);
return 0;
}

T2:选择客栈

  首先这还是一道枚举题,边读入边处理出每种颜色的前缀和,同时记录上一个满足最低消费要求的咖啡馆的位置,每次加上这个位置的同颜色前缀和即可,复杂度O(kn)。需要注意的是答案超过了int的范围,需要开long long,而且一开始做这道题是忽略了可以在自己的旅馆喝咖啡的情况,这是不应该的。

#include <cstdio>
#include <iostream>
using namespace std;
const int N=200005;
long long sum;
int pr,n,k,pm,pn,co,s[N][55];
int main(){
scanf("%d%d%d",&n,&k,&pm);
for(int i=1;i<=n;i++){
scanf("%d%d",&co,&pn);
for(int j=0;j<k;j++)s[i][j]=s[i-1][j];
s[i][co]++; if(pn<=pm)pr=i;
if(pr!=i)sum+=(long long)s[pr][co];
else sum+=(long long)s[pr-1][co];
}
cout<<sum<<endl;
return 0;
}

T3:Mayan游戏

  直接模拟题目中的坠落,清除和操作的过程,直接按操作的字典序搜索,特别注意相同的两个块不要移动,不同的块不要反复交换,此外要有一个判断,当剩余的彩块有一种没到3个时直接剪枝,因为这种情况一定是无法完成的,然后就是一些自己程序的细节问题要多注意。

#include <cstdio>
#include <cstring>
#include <algotithm>
using namespace std;
const int maxx=10,maxy=12,maxc=15;
int n,c,a[maxx][maxy],cnt[maxc],ans[maxx][3];
bool f[maxx][maxy];
void fall(int x){
for(int i=0;i<7;i++){
if(a[x][i]==0){
int j=i+1;
while(j<7&&a[x][j]==0)j++;
if(j==7)return;
else swap(a[x][i],a[x][j]);
}
}
}
bool clear(){
bool flag=false;
for(int i=0;i<5;i++)
for(int j=0;j<7;j++){
if(!a[i][j]) continue;
if(i<3&&a[i][j]==a[i+1][j]&&a[i][j]==a[i+2][j])
{f[i][j]=1;f[i+1][j]=1;f[i+2][j]=1;}
if(j<5&&a[i][j]==a[i][j+1]&&a[i][j]==a[i][j+2])
{f[i][j]=1;f[i][j+1]=1;f[i][j+2]=1;}
}
for(int i=0;i<5;i++)
for(int j=0;a[i][j]&&j<7;j++)if(f[i][j]){
flag=1;
cnt[a[i][j]]--;
a[i][j]=f[i][j]=0;
}
for(int i=0;i<5;i++)fall(i);
return flag;
}
int check(){
int minc=0;
for(int i=1;i<=c;i++)if(cnt[i])
if(!minc||minc>cnt[i])minc=cnt[i];
return minc;
}
void print(){
for (int i=1;i<=n;i++)
printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);
exit(0);
}
void dfs(int move){
int tmpd[maxx][maxy],tmpdc[maxc];
for(int i=0;i<5;i++)for(int j=0;j<7;j++)tmpd[i][j]=a[i][j];
for(int i=1;i<=c;i++)tmpdc[i]=cnt[i];
for (int i=0;i<5;i++)
for(int j=0;a[i][j]&&j<7;j++)
for(int k=1;k>=-1;k-=2)
if(i+k>=0&&i+k<5){
if((k==-1&&a[i-1][j])||a[i][j]==a[i+k][j])continue;
ans[move][0]=i; ans[move][1]=j; ans[move][2]=k;
swap(a[i][j],a[i+k][j]);
fall(i); fall(i+k);
while(clear());
int tmp=check();
if(move==n){if(tmp==0)print();}
else if(tmp>2)dfs(move+1);
for(int i=0;i<5;i++)
for(int j=0;j<7;j++)a[i][j]=tmpd[i][j];
for(int i=1;i<=c;i++)cnt[i]=tmpdc[i];
} }
int main(){
scanf("%d",&n);
int tmp; c=0;
for(int i=0;i<5;i++)
for(int j=0;j<=7;j++){
scanf("%d",&tmp);
if(tmp==0)break;
a[i][j]=tmp;
c=max(c,tmp);
cnt[tmp]++;
}dfs(1);
printf("-1\n");
return 0;
}

DAY2 》

T1:计算系数

  基础的二项式展开,先计算出组合数,然后乘上两个数幂即可。

#include <iostream>
typedef long long LL;
const int mod=10007;
using namespace std;
LL ans,a,b,l,k,m,n,c[1500][1500];
LL power(LL a,LL b,LL m){
LL t,y;
t=1; y=a;
while(b){
if(b&1)t=t*y%m;
y=y*y%m; b>>=1;
}return t;
}
int main(){
cin>>a>>b>>k>>n>>m;
ans=1; c[1][1]=1;
for(int i=2;i<=k+1;i++)
for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
ans=c[k+1][m+1];
ans=ans*power(a,n,mod)%mod;
ans=ans*power(b,m,mod)%mod;
cout<<ans<<endl;
return 0;
}

T2:聪明的质检员

  由题目可得,根据 w 取值的变化,检验结果具有单调性,所以我们二分答案 w,然后对于 check 的书写,可采用前缀和,记录i 位之前有几个大于 w,即用来计算 l,同时,记录下大于 w 的 v 前缀和,之后用 check 与 s 取差,不断更新最小值。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N=200005;
char c;
LL wmax,wmin,ans,tmp,s1,w[N],v[N],h[N],s[N];
int i,j,k,l,m,n,r,mid,r1[N],l1[N];
LL check(LL x){
int i,j;
LL tmp;
memset(h,sizeof(h),0);
memset(s,sizeof(s),0);
h[0]=s[0]=tmp=0;
for(int i=1;i<=n;i++)if(w[i]>=x)
{s[i]=s[i-1]+v[i];h[i]=h[i-1]+1;}
else{s[i]=s[i-1];h[i]=h[i-1];}
for(int i=1;i<=m;i++)
tmp=tmp+(LL)((s[r1[i]]-s[l1[i]-1])*(h[r1[i]]-h[l1[i]-1]));
return tmp;
}
int scan(LL &x){
while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';
}
int main(){
cin>>n>>m>>s1;
wmax=0;
wmin=~0U>>1;
for(int i=1;i<=n;i++){
scan(w[i]);scan(v[i]);
if(w[i]>wmax)wmax=w[i];
if(w[i]<wmin)wmin=w[i];
}
for(int i=1;i<=m;i++)scanf("%d%d",&l1[i],&r1[i]);
l=wmin;r=wmax+1;
ans=abs(check(l)-s1);
do{
mid=(l+r)>>1;
tmp=check(mid);
if(tmp==s1){ans=0;break;}
if(tmp<s1){ans=min(ans,abs(tmp-s1));r=mid-1;}
if(tmp>s1){ans=min(ans,abs(tmp-s1));l=mid+1;}
}while(l<=r);
cout<<ans<<endl;
return 0;
}

T3:观光公交

  这道题需要先求出不用加速器到达某站需要的总时间,这个很好求,就是每次到达前一站最后一个乘客的时间与到前一站的实际时间的最大值加上中间路程所需要的时间,最终时间记为ans.

  然后考虑加速器对时间的影响,采用贪心策略,每个加速器都要用在能使最多人减少时间的地方,需要注意的是,并不是当前在车上的所有人都可以减少时间,因为在如果使用加速器加速后提前到了某站,车上的乘客还是需要在此地等待,时间不变。所以如果在i+1站有会产生等待时间的话,我们在i到i + 1间使用加速器,到i + 1站的乘客的旅行时间都会减一,别的不变,如果没有等待时间,所有人的时间都会减一,所以分情况讨论,计算出每一站公交不在等待上浪费时间最远可以到达的站点,每次求出最大值,在ans中减去,同时维护时间和最远可达站,最后就是答案。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{int st,ar,ta;}a[20000];
int n,m,K,ans,f[20000],at[20000],next[20000],t[20000],sum[20000];
int main(){
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<n;i++)scanf("%d",&t[i]);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a[i].ar,&a[i].st,&a[i].ta);
f[a[i].st]=max(f[a[i].st],a[i].ar);
sum[a[i].ta]++;
}at[1]=0;
for(int i=2;i<=n;i++)sum[i]+=sum[i-1];
for(int i=2;i<=n;i++)at[i]=max(at[i-1],f[i-1])+t[i-1];
for(int i=1;i<=m;i++)ans+=at[a[i].ta]-a[i].ar;
while(K){
next[n]=next[n-1]=n;
for(int i=n-2;i;i--){
if(at[i+1]<=f[i+1])next[i]=i+1;
else next[i]=next[i+1];
}
int maxn=0,j;
for(int i=1;i<=n;i++)
if(sum[next[i]]-sum[i]>maxn&&t[i]>0)maxn=sum[next[i]]-sum[i],j=i;
if(!maxn)break;
ans-=maxn,t[j]--,K--;
at[1]=0;
for(int i=2;i<=n;i++)at[i]=max(at[i-1],f[i-1])+t[i-1];
}
printf("%d\n",ans);
return 0;
}

注意点:

  1.注意数据范围是否超过int,若是需要开long long;

  2.注意C++过程中数组不能开过大,大数组要声明在主程序中,在过程中注意要初始化一下;

  3.读入优化很重要,如果时间允许最好都做一个读入优化;

  4.读题仔细,注意多种情况和一些细枝末节的条件,分类讨论要思考清楚。

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. Excel表格中汉字转拼音

    一.使用“实用汉字转拼音V4.8” 软件 下载地址http://www.orsoon.com/soft/4413.html 或则百度 很多的 二.Excel自定义函数方法: 1.启动Excel 200 ...

  2. GWT工程 —— HostedMode(宿主模式下调试) 所有的运行命令

    Unknown argument: -helpGoogle Web Toolkit 1.7.0HostedMode [-noserver] [-port port-number | "aut ...

  3. A - A

    A - A Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status ...

  4. BZOJ 1935: [Shoi2007]Tree 园丁的烦恼( 差分 + 离散化 + 树状数组 )

    假如矩阵范围小一点就可以直接用二维树状数组维护. 这道题,  差分答案, 然后一维排序, 另一维离散化然后树状数组维护就OK了. ----------------------------------- ...

  5. leetcode find median sorted arrays python

    # @link http://www.cnblogs.com/zuoyuan/p/3759682.html class Solution(object): def findMedianSortedAr ...

  6. JQuery初识

    一.什么是JQuery       JQuery官方网站上是这样解释的:JQuery是一个快速简洁的JavaScript库,它可以简化HTML文档的元素遍历.事件处理.动画及Ajax交互,快速开发We ...

  7. 使用sql语句创建表、修改表、添加列等

    1. 创建表: CREATE TABLE 学生信息 (    学号 varchar(14) IDENTITY(1,1) PRIMARY KEY,    姓名 varchar(8) UNIQUE NOT ...

  8. 一年开发ASP.NET MVC4项目经验总结

    一年开发ASP.NET MVC4项目所用所学技术经验总结 阅读目录 文章背景 前端所用技术摘要 后端所用技术摘要 1. 文章背景 本人2014年从Java转行到C#从事BS项目的开发,刚开始接触的是A ...

  9. codeforces 617E. XOR and Favorite Number 莫队

    题目链接 给n个数, m个询问, 每次询问问你[l, r]区间内有多少对(i, j), 使得a[i]^a[i+1]^......^a[j]结果为k. 维护一个前缀异或值就可以了. 要注意的是 区间[l ...

  10. python自学笔记(一)简单了解python

    脚本解释型语言的内部机制 python先将脚本编译成字节码文件(pyc,pyo) python虚拟机解释并运行字节码文件 编译型语言的内部机制 先将源代码编译成机器码(机器能读懂的代码),生成可执行文 ...