zoukankan      html  css  js  c++  java
  • [noip模拟题]科技节

    【问题描述】

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

    【输入】

          输入文件名为scifest.in。

          输入数据包括多组。

          对于每组数据:

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

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

    【输出】

          输出文件名为scifest.out。

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

    【输入输出样例】

    scifest.in

    scifest.out

    3 3

    0 1 0

    0 0 1

    1 0 0

    4 4

    0 0 0 1

    1 0 0 0

    1 1 0 1

    0 1 0 0

    Yes

    No

    【数据范围】

          对于20%的数据,n≤10,m≤200,数据组数≤10;

          对于60%的数据,n≤16,m≤300,数据组数≤100;

          对于100%的数据,n≤16,m≤300,数据组数≤1,000。


      这题开始以为是用动态规划,后来发现n这么小应该使用搜索,后来经老师介绍,如果纯搜索+数组的话只能过6组数据,而加上二进制就可以全过

      boolean数组其实既浪费内存又浪费时间,1个字节8个二进制位,而事实上储存true和false只用1个二进制位,所以用unsigned int类型的32个二进制位

    来存储这些true和false的数据。其它都比较简单,直接就发代码了

    Code

     1 #include<iostream>
     2 #include<fstream>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 #define k 32
     7 typedef bool boolean;
     8 ifstream fin("scifest.in");
     9 ofstream fout("scifest.out");
    10 boolean found;
    11 int m,n;
    12 int buf;
    13 typedef struct myData{
    14     int peo;
    15     unsigned int activities[10];
    16 }myData;
    17 myData *s;
    18 unsigned int ac[10];
    19 boolean cmp(const myData& a,const myData& b){
    20     return a.peo > b.peo;
    21 }
    22 boolean init(){
    23     if(!(fin>>n>>m)) return false;
    24     s = new myData[(const int)(n + 1)];
    25     found = false;
    26     for(int i = 0;i < n;i++){
    27         s[i].peo = 0;
    28         memset(s[i].activities, 0, sizeof(s[i].activities));
    29         for(int j = 0;j < m;j++){
    30             fin>>buf;
    31             if( buf == 1 ){
    32                 s[i].peo++;
    33                 s[i].activities[j/k] += 1 << (j % k);
    34             }
    35         }
    36     }
    37     sort(s,s + n,cmp);
    38     return true;
    39 }
    40 void free_MyPointer(){
    41     delete[] s;
    42 }
    43 void find(int vi,unsigned int *sed,int join){
    44     if(vi == n){
    45         if(join == m) found = true;
    46         return ;
    47     }
    48     unsigned int t[10];
    49     boolean aFlag = true;
    50     for(int i = 0;i <= m/k;i++){
    51         if((sed[i] & s[vi].activities[i]) != 0){
    52             aFlag = false;
    53             break;
    54         }
    55         t[i] = sed[i] | s[vi].activities[i];
    56     }
    57     if(aFlag)    find(vi + 1, t, join + s[vi].peo);
    58     if(!found)    find(vi + 1, sed, join);
    59 }
    60 int main(){
    61     while(init()){
    62         find(0, ac, 0);
    63         if(found)    fout<<"Yes"<<endl;
    64         else fout<<"No"<<endl;
    65         free_MyPointer();
    66     }
    67     return 0;
    68 }


     

  • 相关阅读:
    c getline
    vim tips
    viksoe.dk UI: Become windowless
    用ls如何实现文件按时间排序查看,谢谢! AIX ChinaUnix.net
    垂直切分大小 : vertical res 30
    commandlinefu.com
    cmake 学习笔记(二) 1+1=2 博客频道 CSDN.NET
    implement split with c++
    分享:spdylay 0.3.8 发布,SDPY 的 C 语言实现
    培乐园《搜索相关性1》—在线播放—优酷网,视频高清在线观看
  • 原文地址:https://www.cnblogs.com/yyf0309/p/5674841.html
Copyright © 2011-2022 走看看