健康的好斯坦奶牛

来源:互联网 发布:复旦大学软件学院就业 编辑:程序博客网 时间:2024/04/27 18:34

穿越栅栏这题是一道 DFS题,但觉得DFS代码太长,就写了投机取巧代码。
这个技巧就是,用位运算,呃呃呃,这么说吧,我现在有一个二进制的数,这个数有g位,第i位数字为1是,表示用这种饲料,0表示不用,这样一来,就只要枚举从0~1(<<)g位了,代码会短很多,时间复杂度也并不见得比DFS要慢。
上代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>int need[100],num[100][100],h[100],n,g;int count(int n){    int ans = 0;    while(n!=0)    {        if(n%2==1)ans++;        n >>= 1;    }    return ans;}bool cmp(int x){    int i = 0;    while(x!=0)    {        if(x%2==0){x >>= 1;i++;continue; }        for(int j = 0;j<n;j++)h[j] += num[i][j];        x >>= 1;i++;    }    for(int i = 0;i<n;i++)        if(need[i]>h[i])return false;    return true;}int main(){    freopen("holsteins.in","r",stdin);    freopen("holsteins.out","w",stdout);    std::cin>>n;    for(int i = 0;i<n;i++)std::cin>>need[i];    std::cin>>g;    for(int i = 0;i<g;i++)        for(int j = 0;j<n;j++)            std::cin>>num[i][j];    int ans = (1<<30)-1;    for(int i = 0;i<(1<<g);i++)    {        for(int i = 0;i<n;i++)h[i] = 0;        if(cmp(i)==false)continue;        ans = count(ans)<=count(i)?ans:i;    }    memset(h,0,sizeof(h));    int i = 1;    std::cout<<count(ans)<<" ";    while(ans!=0)    {        if(ans%2==0){ans >>= 1;i++;continue;}        std::cout<<i<<" ";        ans >>= 1;i++;    }    fclose(stdin);    fclose(stdout);    return 0;}