桶-复习笔记
桶的概念
首先,弄明白什么是一个桶
在一个桶里面只有一种数据,用来表示这种数据的多少

上图为5个桶
有了一个桶,我们可以做到去重,排序,统计等基础操作
例1.1 Luogu P1554
首先,我们求每一个数位
while(x){
int now=x%10;//当前数位
x/=10;
}
我们使用一个长度为 \(n\) 的数组 tot 来表示 \(n\) 个桶
那么我们先输入 \(n,m\),从n枚举到m,对每一个数字单独计算
在计算时,我们把每一个数位上数字对应的桶的大小+1
具体见代码
void solve(int x){
while(x){
int now=x%10;
tot[now]++;
x/=10;
}
}
signed main(){
cin>>n>>m;
for(int i=n;i<=m;i++){
solve(i);
}
for(int i=0;i<=9;i++){
cout<<tot[i]<<' ';
}
return 0;
}
同理,让我们完成二维桶 Luogu P1789与三维桶 Luogu P5729
二维桶(没写完不要看):
点击查看代码
void calhuo(int x,int y){
for(int i=x-1;i<=x+1;i++){
for(int j=y-1;j<=y+1;j++){
tot[i][j]++;
}
}
tot[x+2][y]++;
tot[x-2][y]++;
tot[x][y+2]++;
tot[x][y-2]++;
}
void calying(int x,int y){
for(int i=x-2;i<=x+2;i++){
for(int j=y-2;j<=y+2;j++){
tot[i][j]++;
}
}
}
signed main(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
calhuo(x+2,y+2);
}
for(int i=1;i<=k;i++){
int x,y;
cin>>x>>y;
calying(x+2,y+2);
}
int ans=0;
for(int i=1+2;i<=n+2;i++){
for(int j=1+2;j<=n+2;j++){
if(tot[i][j]==0){
ans++;
}
}
}
cout<<ans;
return 0;
}
三维桶:
点击查看代码
void cal(int a1,int b1,int c1,int a2,int b2,int c2){
for(int i=a1;i<=a2;i++){
for(int j=b1;j<=b2;j++){
for(int k=c1;k<=c2;k++){
tot[i][j][k]++;
}
}
}
}
signed main(){
cin>>w>>x>>h;
cin>>q;
while(q--){
int a,b,c,d,e,f;
cin>>a>>b>>c>>d>>e>>f;
cal(a,b,c,d,e,f);
}
int ans=0;
for(int i=1;i<=w;i++){
for(int j=1;j<=x;j++){
for(int k=1;k<=h;k++){
if(tot[i][j][k]==0){
ans++;
}
}
}
}
cout<<ans;
return 0;
}
桶计数
我们在之前使用了桶标记,现在我们把标记转化为计数
例2.1 Luogu P1598
首先,读入是一个问题,我们使用getline读入4行字符串,getline会自动读至换行,对于每一个字符,我们标记他所在的桶++
输出也是问题,我们这里统计一个桶的最大值,从最大值往1枚举如果桶的计数超过了枚举的数量,就代表这里要输出一个星号
见代码:
signed main(){
for(int j=1;j<=4;j++){
string s;
getline(cin,s);
for(int i=0;i<s.size();i++){
tot[s[i]]++;//桶计数
}
}
int maxi=0;
for(char i='A';i<='Z';i++){
maxi=max(maxi,tot[i]);//最大值
}
for(int i=maxi;i>=1;i--){//枚举
for(char j='A';j<='Z';j++){//枚举字母
if(tot[j]>=i){
cout<<"* ";
}
else{
cout<<" ";//没达到也有输出一个空格
}
}cout<<endl;
}
for(char i='A';i<='Z';i++){//别忘了最后还有一行
cout<<i<<' ';
}
return 0;
}
桶排序
我们用桶标记了元素的数量,现在,可以利用这一情况进行桶排序
例3.1 Luogu P1138
目标是找第k小的整数,通过统计每个数字出现的次数,然后按顺序累加桶的计数。例如,若桶数组为cnt[0...9],则从0到9依次检查sum += cnt[i],当sum >=k时,当前i即为答案。具体实现需注意数字范围和初始化桶数组。
本人(KK_SpongeBob)蒟蒻,写不出好文章,但转载请注明原文链接:https://www.cnblogs.com/OIer-QAQ/p/19095821

浙公网安备 33010602011771号