Purifying Machine
Time Limit: 2000MS |
|
Memory Limit: 65536K |
Total Submissions: 5004 |
|
Accepted: 1444 |
Description
Mike is the owner of a cheese factory. He has 2N cheeses and each cheese are given a binary number from 00...0 to 11...1. To keep his cheese free from viruses, he made himself a purifying machine to clean virus-infected cheese. As a talented programmer, his purifying machine was built in a special the. His purifying machine had N switches, each switch had three states, 1, 0 and *. An operation of a cleaning action according to the states of the N switches. During one operation, at the most one switch can is turned to state *, which can substitute for either 1 or 0. When the machine was turned to a specific state, an operation would clean all the cheeses with corresponding binary numbers. For example, if N equals 6 and the switches is turned to 01*100, the cheeses numbered 010100 and 011100 is under Operat Ion by the machine.
One day , Mike's machine was infected. When Mike found out, he had already do some operations and the cheeses operated by this infected machine were infected t Oo. He cleaned he machine as quickly as he could, and now he needs to clean the infected cheeses with the minimum number of O Perations. If A cheese is infected, cleaning this cheese with the machine one or more times would make this cheese free from virus aga In But if a cheese isn't infected, operation on this cheese would make it go bad.
Now given the infected operations Mike have done and you need to find out the minimum number of operations that must be PE Rformed to clean all the infected cheeses without making no clean cheese go bad.
Input
There is several test cases. Each test case is starts with a line containing the numbers n and M (1 <= n <=, 1 <= M <= 1000). N is the number of switches in the machine and M are the number of infected operations Mike have done. Each of the following M lines contains a switch state of the. A test Case with N = M = 0 ends the input and should not being processed.
Output
for each test case, output one line containing a integer, which is the minimum number of operations Mike needs to do.
Sample Input
3 3*011000110 0
Sample Output
2
Source
Beijing 2005Test Instructions:There are 2^n cheese, corresponding to the number of binary, with the cleaning machine input a binary number can clean up the corresponding cheese, containing * calculated to 0 and 12, each time only one *, so every time *, can simultaneously clear two only one (* in the bit) different binary number, now clean the machine itself infected bacteria, It cleans up the cheese is infected, after the cleaning machine disinfection, asked to clean up a few times to clean up all the infected cheese
#include <cstdio> #include <algorithm> #include <cstring> #include <iostream> #include < cmath> #include <vector> #define MM (A, B) memset (A,b,sizeof (a)) using namespace std;vector<int> g[2200]; int Match[2200],used[2200];int g,b,m,cnt,l,r;int mp[2200],posi[2200];void add_edge (int u,int v) {G[u].push_back (v); G[v].push_back (u);} bool Dfs (int u) {used[u]=1; for (int i=0;i<g[u].size (); i++) {int v=g[u][i]; int W=MATCH[V]; if (w<0| |! Used[w]&&dfs (W)) {match[u]=v; Match[v]=u; return true; }} return false;} int Bipartite_match () {MM (match,-1); int res=0; for (int i=1;i<=1000+r;i++) if (match[i]<0) {memset (used,0,sizeof (used)); if (Dfs (i)) res++; } return res; BOOL Onlyonedifer (int i,int j) {int c= (I^J); Return (c&& ((c& (c-1)) ==0);} Handling i,j, two digit binary represents only one different template bool Jione (int i) {int j=0; WhIle (i) {if (i&1) j + +; i>>=1; } return j%2==1;} void Build () {l=0;r=0; for (int i=1;i<=cnt;i++) {if (Jione (Mp[i])) {l++; Posi[l]=mp[i]; } else {r++; Posi[1000+r]=mp[i]; }} for (int i=1;i<=1000+r;i++) g[i].clear (); for (int i=1;i<=l;i++) for (int j=1;j<=r;j++) if (Onlyonedifer (posi[i],posi[j+1000])) Add_edge (i,j+1000);} Char S[15];int main () {int n,m; while (~SCANF ("%d%d", &n,&m) && (n| | m)) {cnt=0; MM (mp,0); for (int i=1;i<=m;i++) {scanf ("%s", s); int flag=0; ++cnt; for (int j=0;j<n;j++) {if (s[j]== ' * ') { flag=j+1; Mp[cnt]= (mp[cnt]<<1) +0; } else mp[cnt]= (mp[cnt]<<1) +s[j]-' 0 '; } if (flag) {mp[cnt+1]= (mp[cnt]| ( 1<< (n-1-(flag-1))); ++cnt; }} sort (mp+1,mp+cnt+1);//unique before processing cnt=unique (mp+1,mp+cnt+1)-(mp+1);//go to heavy build (); int W=bipartite_match (); printf ("%d\n", w+cnt-2*w); } return 0;}
Analysis: A lot of details of a problem;
1. Handle two digit binary representation there is only one different template, see Code
2. When the *, the binary matching, the building is very skillful, will 1 appear the number of odd number of left, even several times the right to put
3. To perform the redo process
The 4.& operator has a low priority
POJ 2724 Cheese Disinfection Machine Two-point matching map comparison difficult to think