cogs luogu [NOIP2011] 选择客栈

★★   输入文件:hotel.in   输出文件:hotel.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】

丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从1 到n 编号。每家客栈都按照某一种色调进行装饰(总共k 种,用整数0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。
两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过p。
他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过p元的咖啡店小聚。

【输入】
输入文件hotel.in,共n+1 行。
第一行三个整数n,k,p,每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;
接下来的n 行,第i+1 行两个整数,之间用一个空格隔开,分别表示i 号客栈的装饰色调和i 号客栈的咖啡店的最低消费。

【输出】
输出文件名为hotel.out。

输出只有一行,一个整数,表示可选的住宿方案的总数。

【输入输出样例1】

hotel.in

5 2 3
0 5
1 3
0 2
1 4
1 5

hotel.out

3

【输入输出样例说明】

客栈编号
色调 0 1 0 1 1
最低消费 5 3 2 4 5

2 人要住同样色调的客栈,所有可选的住宿方案包括:住客栈①③,②④,②⑤,④⑤,但是若选择住4、5 号客栈的话,4、5 号客栈之间的咖啡店的最低消费是4,而两人能承受的最低消费是3 元,所以不满足要求。因此只有前3 种方案可选。

【数据范围】
对于30%的数据,有n≤100;
对于50%的数据,有n≤1,000;
对于100%的数据,有2≤n≤200,000, 0≤K≤50,0≤P≤100, 0≤最低消费≤100, K≤50,0≤P≤100,

暴力60分:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 
 7 const int N = 200010;
 8 using namespace std;
 9 
10 int v[N];
11 int sd[N];
12 int a[N];
13 
14 inline int read()
15 {
16     int x=0,f=1;
17     char c=getchar();
18     while(c<'0'||c>'9') {if(c=='-')f=-1; c=getchar();}
19     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
20     return x*f;
21 }
22 
23 int main()
24 {
25     freopen("hotel.in","r",stdin);
26     freopen("hotel.out","w",stdout);
27     int n=read();
28     int m=read();
29     int p=read();
30     sd[1]=read();
31     v[1]=read();
32     for(int i=2;i<=n;i++)
33     {
34         sd[i]=read();
35         v[i]=read();
36     }
37     int Answer=0;
38     
39     for(int i=1;i<n;i++)
40         for(int j=i+1;j<=n;j++)
41         {
42             if(sd[i]!=sd[j])continue ;
43             int minn=999999;
44             for(int k=i;k<=j;k++)
45                 minn=min(minn,v[k]);
46             if(minn<=p)Answer++;
47         }
48         
49     printf("%d",Answer);
50     return 0;
51 }

NB代码:(by http://www.cnblogs.com/mjtcn/p/6900589.html

思路是:

当找到一个旅店时,如果他左边有一个符合要求的咖啡店,那么再往左边看,如果有一个颜色
相同的旅店,那么这就是一种方法,那么如果以这个右边的旅店往左,将所有在左边而且颜色与之相
同的旅店数相加,就能得出所有的住宿方法了。那么用这个办法,用所有的对应点对应过去,就能最快的时间内找
出所用的酒店了。
用s数组临时记录当前同样颜色的酒店出现的次数,也就是找的对应点临时记录。
用c数组是记录同一种颜色中的酒店所出现的最后一次的位置;
用num数组记录同一种颜色的酒店的出现次数,

 1 #include<cstdio>
 2 
 3 const int N = 200100;
 4 
 5 int n,k,p,col,mon,now,ans;
 6 
 7 int num[N],s[N],c[N];
 8 
 9 int main()
10 {
11     scanf("%d%d%d",&n,&k,&p);
12     
13     for(int i=1;i<=n;++i)
14     {
15         scanf("%d%d",&col,&mon);
16         if(mon<=p) now = i;
17         if(now>=c[col]) s[col] = num[col];
18         c[col] = i;
19         ans += s[col];
20         num[col]++;
21     }
22     
23     printf("%d",ans);    
24     return 0;
25 }
原文地址:https://www.cnblogs.com/lyqlyq/p/6905338.html