题目
题目描述
丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0∼k−1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。
两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过p 。
他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过 p 元的咖啡店小聚。
输入格式
共 n+1 行。
第一行三个整数 n,k,p,每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;
接下来的 n 行,第 i+1 行两个整数,之间用一个空格隔开,分别表示 i 号客栈的装饰色调 ai 和 i 号客栈的咖啡店的最低消费 bi。
输出格式
一个整数,表示可选的住宿方案的总数。
输入输出样例
输入 #1
5 2 3 0 5 1 3 0 2 1 4 1 5
输出 #1
3
说明/提示
样例解释
2 人要住同样色调的客栈,所有可选的住宿方案包括:住客栈①③,②④,②⑤,④⑤,但是若选择住 4,5号客栈的话,4,5 号客栈之间的咖啡店的最低消费是 4 ,而两人能承受的最低消费是 3 元,所以不满足要求。因此只有前 3 种方案可选。
数据范围
对于 30% 的数据,有 n≤100 ;
对于 50% 的数据,有 n≤1000;
对于 100% 的数据,有 2≤n≤2×10^5,1≤k≤50,0≤p≤100,0≤bi≤100。
分析
这道题的50% 的数据 n≤1000,所以用暴力方法就可以拿到50+,最高能拿到70分(当然,由于这道题的测试点有点水,所以对暴力程序进行剪枝也能拿到100分)
这道题的满分做法数据范围很大,得出的答案也很大,所以用来存储方案数的变量都得定义成long long 类型
暴力代码(70分)
#include <bits/stdc++.h>
using namespace std;
int n,k,p,a[200005],b[200005],g[200005],cnt;
long long ans;
int main()
{
int i,j,t;
scanf("%d%d%d",&n,&k,&p);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
if(b[i]<=p) g[++cnt]=i;
}
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
if(a[i]==a[j])
{
for(t=i;t<=j;t++)
{
if(b[t]<=p)
{
ans++;break;
}
}
}
}
}
cout<<ans;
return 0;
}
关于这个代码的讲解就不用多说了吧
满分代码讲解
1.变量定义
int n,k,p,a[200005],b[200005];
long long sum[105],res;
第一行的变量含义和题目中的相同,第二行的sum[i]代表选择i号色调的方案数,res代表最终方案数
2.输入
scanf("%d%d%d",&n,&k,&p);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
这里就不用多说了吧
3.得出方案数(程序中最重要的部分)
for(i=1;i<=n;i++)
{
if(b[i]>p) res+=sum[a[i]];
else
{
while(j<i)
{
j++;
sum[a[j]]++;
}
res+=sum[a[i]]-1;
}
}
如果当前客栈的最低消费小于等于p,则把之前每一个客栈所对应的色调的方案数加1,最终答案就加上该客栈色调的方案数减去它自己。注意加过的就不要重复加了,即j就不要重新归零了,但j刚开始的初值要等于0;
如果当前客栈的最低消费大于p,则最终答案就加上该客栈色调的方案数,注意这里就不要减去它自己了
最后再输出最终答案res,整个程序也就结束了
完整AC代码
#include <bits/stdc++.h>
using namespace std;
int n,k,p,a[200005],b[200005];
long long sum[105],res;
int main()
{
int i,j=0;
scanf("%d%d%d",&n,&k,&p);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
for(i=1;i<=n;i++)
{
if(b[i]>p) res+=sum[a[i]];
else
{
while(j<i)
{
j++;
sum[a[j]]++;
}
res+=sum[a[i]]-1;
}
}
cout<<res;
return 0;
}