zoukankan      html  css  js  c++  java
  • 科技节(位运算)

    【问题描述】

          一年一度的科技节即将到来。同学们报名各项活动的名单交到了方克顺校长那,结果校长一看皱了眉头:这帮学生热情竟然如此高涨,每个人都报那么多活动,还要不要认真学习了?!这样不行!……于是,校长要求减少一些活动,使每位学生只能参加一项(一名同学要参加某活动,必须已报名且该活动未被去掉)。当然,他也不希望哪位同学因此不能参加任何活动。他想知道自己的方案能否实行。

    【输入】

          输入文件名为scifest.in。

          输入数据包括多组。

          对于每组数据:

          第一行两个正整数n和m,分别表示活动数和学生数。

          接下来n行,每行m个为0或1的数。第i+1行第j列的数若为1,表示j同学报名参加活动i,否则表示j同学没有报名参加活动i。

    【输出】

          输出文件名为scifest.out。

    对于每组数据输出一行,若校长方案可行则输出“Yes”,否则输出“No”。(均不包括引号)

    【样例输入1】

    3 3

    0 1 0

    0 0 1

    1 0 0

    4

    0 0 0 1

    1 0 0 0

    1 1 0 1

    0 1 0 0

    【样例输出1】

    Yes

    No

    位运算代码:

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    using namespace std;
    long x[20][10];
    long h[20];//一个活动的学生总数
    long n,m;
    long k=0;
    int c;char yes=false;
    void solve(long p,long qw[10],long per)//选第P个,前数组,完成的人数
    {
      if(yes==true)return ;
      if(p==n)
      {
        if(per==m)
        {
          yes=true;
          return ;
        }
        return ;
      }
    long t[10];
      for(k=0;k<=9;k++)
      {
        if((qw[k]&x[p][k])>0)break;
        t[k]=qw[k]|x[p][k];
      }
      if(k==10)solve(p+1,t,per+h[p]);
      if(yes==false) solve(p+1,qw,per);
    }
    int main()
    {
      ios::sync_with_stdio(false);
      freopen("scifest.in","r",stdin);
      freopen("scifest.out","w",stdout);
      while(cin>>n>>m)//活动数,学生数
      {
        memset(x,0,sizeof(x));
        memset(h,0,sizeof(h));
        yes=false;
        for(int i=0;i<=n-1;i++)
        {
          h[i]=0;
          for(int j=0;j<=m-1;j++)
          {
            cin>>c;
            if(c==1)
            {
              x[i][j/31]+=1<<(j%31);
              h[i]++;
            }
          }
        }
        for(int i=0;i<=n-2;i++)
        for(int j=i+1;j<=n-1;j++)
        if(h[i]<h[j])//降序
        {
          k=h[i];h[i]=h[j];h[j]=k;
          for(int q=0;q<=9;q++)
        {
            k=x[i][q];x[i][q]=x[j][q];x[j][q]=k;
          }
        }
        solve(0,x[19],0);
        if(yes==true)cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
      }
    }

    感想:此题一开始根本没想到用位运算,看到题后先想到的是搜索。如果用搜索的话,还要用排序将活动选的人多的排在前面降序,这样剪枝效果很好,我也没有想到。。。。以后看到这种0、1的题后,我应该先想一下能不能用位运算做(虽然掌握不熟练。)

  • 相关阅读:
    Git学习笔记06-版本回退
    python3+selenium入门07-元素等待
    [cerc2017J]Justified Jungle
    [codeforces126B]Password
    计算几何基础模板
    floyd路径记录
    [数据结构复习]层序建立二叉树
    [patl2-011]玩转二叉树
    [poj3348]Cows
    [poj3347]Kadj Squares
  • 原文地址:https://www.cnblogs.com/937337156Zhang/p/5675239.html
Copyright © 2011-2022 走看看