2077:【21CSPJ普及组】小熊的果篮(fruit)(史上最强)


一,暴力写法

首先for找到第一个没有挑选过的水果的种类,再取反,如果t != a[i]并且没被取过,则t = a[i],在输出t,将它标记为取过,最后输出,sum++,重复以上操作直到总共去的水果数(su,)>=n,即可。

#include <bits/stdc++.h>
using namespace std;
long long n,sum;
bool a[1000001],vis[1000001],t;
int main()
{
  scanf("%lld",&n);
  for(int i = 1; i <= n; i++) scanf("%lld",&a[i]);
  while(sum < n)
  {
    for(int i = 1; i <= n; i++)
      if(vis[i] == 0)
      {
        t = a[i];
        if(t == 1) t = 0;
        else t = 1;
        break;
      }
    for(int i = 1; i <= n; i++)
      if(t != a[i] && vis[i] == 0)
      {
        t = a[i];
        printf("%d ",i);
        vis[i] = 1;
        sum++;
      }
    printf("\n");
  }
  return 0;
}

 


二, 数组模拟链表(正解)

#include <bits/stdc++.h>
using namespace std;
struct dot
{
  int l,r,v;
} a[1000001];
int q[1000001],t,n,m;
void erase(int x)
{
  a[a[x].l].r = a[x].r;
  a[a[x].r].l = a[x].l;
}
int main()
{
  scanf("%d",&n);
  a[0].v = -1;//双向链表初始化
  a[0].r = 1;//双向链表初始化
  a[n + 1].v = -1;//双向链表初始化
  a[n + 1].l = n; //双向链表初始化
  for(int i = 1; i <= n; i++)
  {
    scanf("%d",&a[i].v);
    a[i].l = i - 1;//双向链表初始化
    a[i].r = i + 1;//双向链表初始化
    if(a[i].v != a[i - 1].v)
    {
      m++;
      q[m] = i;
    }
  }
  while(1)
  {
    if(m == 0) break;
    n = m;
    m = 0;
    for(int i = 1; i <= n; i++)
    {
      t = q[i];
      printf("%d ",t);
      erase(t);//删除块头
      if(a[t].v == a[a[t].r].v && a[t].v != a[a[t].l].v)//如果下一个跟后一个相同,且和前一个不同,则是块头
      {
        m++;
        q[m] = a[t].r;//每轮块头越来越少,继续用q数组
      }
    }
    printf("\n");
  }
  return 0;
}

 视频:2021信息学奥赛CSP-J复赛详解 力争把每个细节讲透彻_哔哩哔哩_bilibili

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值