1. 题目
2.
1)70分:
①思路
very easy 单纯暴力枚举
三重循环,分别枚举第一家客栈 第二家客栈和咖啡店的位置,中间内容判断色调数目是否一样,一样的话看咖啡馆的价钱是否超过p,如果价钱不超过p且色调数目一样,则符合条件,sum++
②核心代码:
for(x=1;x<=n;x++)//枚举第一家
{
for(y=x+1;y<=n;y++)//第二家
{
if(hotel[x].a ==hotel[y].a )//色调数目是否相同
{
for(z=x;z<=y;z++)//咖啡店位置
{
if(hotel[z].b <=p)//咖啡馆价钱
{
sum++;
break;
}
}
}
}
}
2)满分思路
①题目重塑:
我们要在一维数组中选择两个数a,b 并从a~b之间选择一个数Pc
满足· a,b 的色调数目相同
· Pc<=p
求满足条件的a b 组数
②思路:
为了降低循环层数,我们思考,是否可以只枚举一个客栈,通过某种计算或者操作得到另一个客栈的个数呢
答案是肯定的:我们发现只要得知一个点b(编号较大的客栈的位置),判断离他最近的咖啡馆的位置,记录这个咖啡馆之前与b色调数目相同的点的个数,一直累加,就能得到答案。
思路解释:我们知道,只要a,b 之间有一个咖啡馆就行,不考虑咖啡馆的位置,即咖啡馆的位置不会影响最后输出的个数答案,所以只要知道离点b最近的咖啡馆之前与b色调数目相同的客栈的个数,相加即可
但是,为什么是离点b最近的咖啡馆而不是第二近,第三近甚至是最远的呢?
因为根据题目要求,最后输出的方案数一定是最多的(全的,不重不漏),只有当咖啡馆离得最近时,咖啡馆前面所包含的点数更多,那么相应的,枚举到的点a的个数就有可能最多
③核心代码:
int j=0;
for(i=1;i<=n;i++)
{
if(hotel[i].b >p) res+=sum[hotel[i].a ];
else
{
while(j<i)
{
j++;
sum[hotel[j].a ]++;
}
res+=sum[hotel[i].a ]-1;
}
}
因为在循环中,我首先j++,所以j的初始值为0
这里采用了桶排序的思想,sum[颜色]++
枚举1~n,判断他能否作为咖啡馆,不能的话,直接加 / 离他最近的咖啡馆之前 / 与他颜色相同的数字 / 的个数(句子有点儿长,画个断句)
如果可以的话,更新最近咖啡馆,因为题目中说客栈a b 也可以作为咖啡馆
直接计算出此咖啡馆前所有包含颜色的数字的个数,因为我们不知道后面出现的颜色到底有几种,最后res+=我们枚举到的这个点颜色相同的个数-1
为什么要-1呢?
因为在枚举时,我们的 j 最后的值会等于i,所以在相同颜色的计算中,把当前我们枚举到的这个点加进去了,所以最后的个数要-1
④根据样例,解释代码:
p=3
·i=1: Pc=5>3 无法做咖啡馆,直接加离他最近的咖啡馆前相同颜色的个数 res=0
`i=2:Pc=3<=3 可以做咖啡馆,sum[0]=1,sum[1]=1(他自己); res+=sum[1]-1=0
以此类推~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
·i=3:Pc=2<=3 √,sum[0]=2,sum[1]=1;res+=sum[0]-1=0+(2-1)=1
`i=4:Pc=4>3 × 不更新sum的值 sum[0]=2,sum[1]=1;res+=sum[1]=1+1=2
`i=5:Pc=5>3 × 不更新sum的值 sum[0]=2,sum[1]=1; res+=sum[1]=2+1=3
最后输出res=3
3.完整代码:
70:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,k,p;
struct node
{
int a,b;
}hotel[N];
int flag[N];
int main()
{
int i,j,x,y,z,sum=0;
cin>>n>>k>>p;
for(i=1;i<=n;i++)
{
cin>>hotel[i].a >>hotel[i].b ;
}
for(x=1;x<=n;x++)//枚举第一家
{
for(y=x+1;y<=n;y++)
{
if(hotel[x].a ==hotel[y].a )//颜色相同
{
for(z=x;z<=y;z++)
{
if(hotel[z].b <=p)//m
{
sum++;
break;
}
}
}
}
}
cout<<sum;
return 0;
}
100:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,k,p;
struct node
{
int a,b;
}hotel[N];
int flag[N];
int sum[N];
int main()
{
int i,x,y,z,res=0;
cin>>n>>k>>p;
for(i=1;i<=n;i++)
{
cin>>hotel[i].a >>hotel[i].b ;
}
int j=0;
for(i=1;i<=n;i++)
{
if(hotel[i].b >p) res+=sum[hotel[i].a ];
else
{
while(j<i)
{
j++;
sum[hotel[j].a ]++;
}
res+=sum[hotel[i].a ]-1;
}
}
cout<<res;
return 0;
}