zoukankan      html  css  js  c++  java
  • cf534D 枚举握手次数

    题意:
          有n个学生进教室,先后顺序不同,每个人进去后会和当前在教室里的人握手,并且记录人数,而且当教室里有超过三个人的时候 他们有可能组队去参加比赛,后来的人看不到他们。


    思路:

         这个题目还行挺有意思的,我们可以一个人一个人来模拟,就是枚举握手次数,然后在相应的里面找到一个,如果一个都找不到就-3,到最后就行了,比如一开始我们枚举0,就是握手次数是0的,如果找到有0,那么这个人就是第一个人,如果0的不唯一的话随便挑一个就行,找到后就+1,找握手次数为1的,找到后就是第二个进来的,然后+1,找2的...如果当前握手次数找不到的话就-3,找到就继续,还找不到就还-3,这样如果那次当前枚举次数小于0了,那么就说明失败了,就是无解,还有就是找到的时候不能暴力去找,可以用个二维容器什么的,我用的是前向星配合类似DINIC里面那个优化(职业病啊),比如当前i这个人的握手次数是3,那么就连边3->i,这样当我们想在3里面删除的时候随便找一个就行,删除之后记得这样处理 list[s] = E[k].next,就是下次直接从下一个开始就行,这个地方怎么处理都行,顺手就行,用容器还有链表啥的都行,不多说了,关键是想到枚举握手次数的那个地方就好办了。


    #include<stdio.h>
    #include<string.h>
    
    #define N_node 200005
    #define N_edge 250005
    
    typedef struct
    {
        int to ,next;
    }STAR;
    
    STAR E[N_edge];
    int list[N_node] ,tot;
    int mkc[N_node];
    int Ans[N_node] ,AT;
    
    void add(int a ,int b)
    {
        //printf("%d %d**
    " ,a ,b);
        E[++tot].to = b;
        E[tot].next = list[a];
        list[a] = tot;
    }
    
    int main ()
    {
        int n ,i ,a ,b;
        while(~scanf("%d" ,&n))
        {
            memset(list ,0 ,sizeof(list)) ,tot = 1;
            memset(mkc ,0 ,sizeof(mkc));
            for(i = 1 ;i <= n ;i ++)
            {
                b = i;
                scanf("%d" ,&a);
                add(a ,b);
                mkc[a] ++;
            }
            int nowc = 0;
            AT = 0;
    
            while(nowc >= 0 && AT != n)
            {
                if(!mkc[nowc]) nowc -= 3;
                else
                for(int k = list[nowc] ;k ;k = E[k].next)
                {
                     Ans[++AT] = E[k].to;
                     mkc[nowc]--;
                     list[nowc] = E[k].next;
                     nowc ++;
                     break;
                }
                //printf("%d
    " ,nowc);
            }
            if(AT == n)
            {
                printf("Possible
    ");
                for(i = 1 ;i <= n ;i ++)
                if(i == n) printf("%d
    " ,Ans[i]);
                else printf("%d " ,Ans[i]);
            }
            else printf("Impossible
    ");
        }
        return 0;
    
    }
    
    
    
    
    
    


  • 相关阅读:
    AM8 自定义表情包的实现方法
    Create STKNetDiskC Instance Error
    怎样实现文件发文功能
    企业云盘的数据备份
    一种可行的文档协同编辑方法实现
    【OI】二分图最大匹配
    【OI】位运算操作
    【OI】关于快速幂的简单理解
    【OI】线性筛
    【OI】指针线段树&指针
  • 原文地址:https://www.cnblogs.com/csnd/p/12062412.html
Copyright © 2011-2022 走看看