USACO 3.1 Contact (contact)

来源:互联网 发布:大数据的基本概念 编辑:程序博客网 时间:2024/05/18 17:57
/* 经典的位运算解题,边读入边计算。 设置极限掩码为limit=(1<<(B))-1; //2的B此次方-1 每读入一个二进制数0或1,令unsigned int数字串str=((str<<1)+c) & limit; 然后扫描str,从末尾向前扫描i=(A到B)位,把所得的数字串t最高位添加1,以区别有前导0的串,例如001和01,添加后变为1001和101mask=(1<<i)-1;mask2=mask+1;t=(S & mask) | mask2;用哈希表记录t的频率 hash[t]++;最后再排序按格式输出即可,一定要小心输出格式。-- refer to byVoid*//*ID: haolink1PROG: contactLANG: C++*///#include <iostream>#include <fstream>#include <vector>#include <algorithm>    // std::sortusing namespace std;typedef unsigned int u_int;class Pattern{public:    u_int freq_;    u_int value_;    Pattern(int freq,u_int value):        freq_(freq),value_(value){}};int A = 0,B = 0,N = 0;const int MAX = (1<<13);u_int hash[MAX];void Vote(unsigned int str, unsigned int str_len){    for(int i = A; i <= B && i <= str_len; i++){       u_int mask = (1 << i) -1;       u_int mask2 = mask + 1;       u_int t = (str & mask) | mask2;       hash[t]++;    } }bool Compare(Pattern p1,Pattern p2 ){    if(p1.freq_ > p2.freq_){        return true;     }else if(p1.freq_ == p2.freq_ && p1.value_ < p2.value_){//Shorter string have less value,eg 101(len = 2) and 1001(len =3)        return true;    }else return false;}void ChangeFormat(u_int source,char target[]){    int bit_num = A;    for(;bit_num <= B; bit_num++){        if(!(source >> (bit_num+1)))            break;    }    for(int i = bit_num -1; i >= 0; i--){        if(source & (1 <<(bit_num - i - 1))){            target[i] = '1';        }else{            target[i] = '0';        }    }    target[bit_num] = '\0';}int main(){    ifstream fin("contact.in");    ofstream cout("contact.out");    fin >> A >> B >> N;    char val;    unsigned int limit = (1 << B)-1;    unsigned int str, str_len = 0;    while(fin >> val){        val -= 48;        str = ((str << 1) + val) & limit;//The digit highter then B will be kicked off by "limit";        str_len ++;        Vote(str,str_len);    }     vector<Pattern> patterns;    for(int i = 0; i < MAX; i++){        if(hash[i] != 0){            patterns.push_back(Pattern(hash[i],i));        }    }    sort(patterns.begin(),patterns.end(),Compare);    u_int cur_freq = -1 ;     int counter = 0;    int per_line = 1;    int len = patterns.size();    for(int i = 0; i < len; i++){        char target[13];        if(patterns[i].freq_ < cur_freq){            counter++;            per_line = 1;            if(counter > N){                break;            }            cur_freq = patterns[i].freq_;            cout << patterns[i].freq_ << endl;            ChangeFormat(patterns[i].value_,target);            cout << target;        }else{            ChangeFormat(patterns[i].value_,target);            cout << target;        }        //Note condition 1 should put first because  per_line == 0 can be caught by condition 2;        if((i+1 == len) || (patterns[i+1].freq_ < cur_freq) || (per_line == 0))//condition 1            cout << endl;        else if(i+1 < len && patterns[i+1].freq_ == cur_freq)//condition 2            cout <<" ";        ++per_line;        per_line = per_line % 6;    }    return 0;}

0 0