11.题目:编号3272 小蓝的漆房

题目:

 ###本题主要考察暴力,枚举,模拟

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int a[N],b[N];
int main(){
  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  int num;cin>>num;
  //样例个数循环
  for(int i=1;i<=num;++i){
  int n,k,mi=INT_MAX;
  cin>>n>>k;
  //颜色入数组
  for(int j=1;j<=n;++j)cin>>a[j];
    //60种颜色遍历
    for(int j=1;j<=60;++j){
      int cnt=0;
      //保证数组初始化
      for(int h=1;h<=n;++h)b[h]=a[h];
      //每重案例 每种颜色 为每个房子遍历涂色
      for(int h=1;h<=n;++h){
        if(b[h]!=j){
          //操作k区间
          for(int z=h;z<=h+k-1;++z)b[z]=j;
          //下一次要操作的房子
          h+=k-1;
          cnt++;
       }
     }
     mi=min(mi,cnt);
   }
   cout<<mi<<'\n';
 }
  return 0;
}

整体思路:

  1. 颜色只有60种,可以将每一种情况对该k长度的区间的操作都遍历
  2. 循环j表示颜色,建两个数组只对第二个数组进行操作,每次用第一个数组给第二个数组初始化
  3. 用h表示该房子的下标,循环中的判断条件z<=h+k-1是因为该下标z也被操作了,所以要减去1,否则操作范围会有误(或者这样写也可以z<h+k)由于++h,每重循环都对下标加了1,所以下一次操作的房子一定要是h+=k-1,进入下一次循环的时候会自动的加上步长就是(h+=k)
  4. 每次都将次数与mi作比较,最终输出最小的次数

下面是第二种代码:(个人认为这份代码要优于上面的)

#include <bits/stdc++.h>
using namespace std;
int main() {
  int t; cin >> t;
  for (int i = 0, n, k; i < t; ++i) {
      cin >> n >> k;
      vector<int> arr(n);
      unordered_set<int> s;
      for (int j = 0; j < n; ++j) {
          cin >> arr[j];
          s.insert(arr[j]);  //一个集合,防止重复记录
      }
      int ans = INT_MAX;
      for(auto &x : s) {
          int cnt = 0;
          for(int j = 0; j < n; ++j) {
              if(arr[j] == x) continue;  //如果当前颜色和我要涂的颜色一样,那么跳过
              cnt ++;
              j += k - 1;   //否则将k区间内的颜色全部涂该种颜色,由于上面有++j,这里要-1
          }
          ans = min(ans, cnt);  //记录最小的就是答案
      }
      cout << ans << endl;
  }
  return 0;
}

这份代码用vector和unordered_set容器做了存储,大体上思路与上一份代码是一致的,这份代码最大的亮点就在于利用了unordered_set容器不重复的特性,无需将60种颜色都遍历(只遍历出现的颜色即可)小亮点在于他使用continue,避免了对数据的操作,直接使用下标来完成了上面代码繁琐的循环

  • 31
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值