The Problem
A marathon runner uses a pedometer with which he is having problems. In the pedometer the symbols are represented by seven segments (or LEDs):
But the pedometer does not work properly (possibly the sweat affected the batteries) and only some of the LEDs are active. The runner wants to know if all the possible symbols:
can be correctly identified. For example, when the active LEDs are:
numbers 2 and 3 are seen as:
so they cannot be distinguished. But when the active LEDs are:
the numbers are seen as:
and all of them have a different representation.
Because the runner teaches algorithms at University, and he has some hours to think while he is running, he has thought up a programming problem which generalizes the problem of his sweat pedometer. The problem consists of obtaining the minimum number of active LEDs necessary to identify each one of the symbols, given a number P of LEDs, and N symbols to be represented with these LEDs (along with the codification of each symbol).
For example, in the previous sample P = 7 and N = 10. Supposing the LEDs are numbered as:
The codification of the symbols is: "0" = 1 1 1 0 1 1 1; "1" = 0 0 1 0 0 1 0; "2" = 1 0 1 1 1 0 1; "3" = 1 0 1 1 0 1 1; "4" = 0 1 1 1 0 1 0; "5" = 1 1 0 1 0 1 1; "6" = 1 1 0 1 1 1 1; "7" = 1 0 1 0 0 1 1; "8" = 1 1 1 1 1 1 1; "9" = 1 1 1 1 0 1 1. In this case, LEDs 5 and 6 can be suppressed without losing information, so the solution is 5.
The Input
The input file consists of a first line with the number of problems to solve. Each problem consists of a first line with the number of LEDs (P), a second line with the number of symbols (N), and N lines each one with the codification of a symbol. For each symbol, the codification is a succession of 0s and 1s, with a space between them. A 1 means the corresponding LED is part of the codification of the symbol. The maximum value of P is 15 and the maximum value of N is 100. All the symbols have different codifications.
The Output
The output will consist of a line for each problem, with the minimum number of active LEDs necessary to identify all the given symbols.
Sample Input
2 7 10 1 1 1 0 1 1 1 0 0 1 0 0 1 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 1 0 1 0 1 1 0 1 0 1 1 1 1 0 1 1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 6 10 0 1 1 1 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 1 1 0 1 0 0 1 0 0 1 0 0 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 1 0 0 0 1 1 0 0 0
Sample Output
5 4
第一种解法(超时)
#define RUN #ifdef RUN #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <vector> #include <list> #include <cctype> #include <algorithm> #include <utility> #include <math.h> #include <ctime> using namespace std; #define MAXN 110 int P; // Number of LEDs, eg:7 列数 int N; // Number of symbols, eg:10 行数 char buf[101][16]; // 存储输入序列 char tmp[101][16]; // buf的复制 int myset[16]; // 排列 bool b[2^16+1]; int minOnes; void printout(){ for(int i=0; i<N; i++){ for(int j=0; j<P; j++){ cout << buf[i][j]; } printf("\n"); } } void printout2(){ for(int i=0; i<N; i++){ for(int j=0; j<P; j++){ cout << tmp[i][j]; } printf("\n"); } cout << "===================" << endl; } int cmp(const void *a, const void *b){ return strcmp((char*)a, (char*)b); } void copyBuf(){ for(int i=0; i<101; i++){ for(int j=0; j<16; j++){ tmp[i][j] = buf[i][j]; } } } bool isSame(char* a, char* b){ for(int i=0; i<P; i++){ if(a[i] != b[i]){ return false; } } return true; } void decide(){ int ones = 0; for(int col=0; col<P; col++){ //printf("%d ", myset[i]); if(myset[col] == 1){ ones++; } //第i列为0,即第i列不被选中,因此可以把tmp中的第i列全部赋值为0 else{ //memcpy(tmp, buf, sizeof(buf)); copyBuf(); //printout2(); for(int row=0; row<N; row++){ tmp[row][col] = '0'; } //先排列一遍 qsort(tmp, N, sizeof(tmp[0]), cmp); //检验是否有重复 for(int i=0; i<N-1; i++){ if(isSame(tmp[i], tmp[i+1])){ return; } } if(ones < minOnes){ minOnes = ones; } } } //printf("\n"); } //产生00..0 到11..1的全部组合,共2^7种组合 void subset(int cur, int n){ if(cur == n){ decide(); return; } else{ myset[cur] = 1; subset(cur+1, n); myset[cur] = 0; subset(cur+1, n); } } int main(){ #ifndef ONLINE_JUDGE freopen("11205.in", "r", stdin); freopen("out.out", "w", stdout); #endif int cnt; cin >> cnt; memset(b, false, sizeof(b)); while(cnt--){ cin >> P >> N; for(int j=0; j<N; j++){ for(int k=0; k<P; k++){ cin >> buf[j][k]; } } minOnes = P; //printout(); subset(0, P); printf("%d\n", minOnes); } } #endif
第二种解法:
参考思想 http://www.questtosolve.com/browse.php?pid=11205
There are up to 15 different LEDs, so there are 2^15 different ways in which they might be active/broken. We can easily test all 100 * 2^15 possibilities.
Represent each symbol as an integer in binary. So, 1 1 0 1 0 is stored as 26 (or 11 if you start from the left; doesn't matter which way you do it). For i from 1 to 2^p, AND together each symbol with i. Then, check if every symbol is unique under this bitmask. We can't afford to do an O(N^2) comparison, so make a boolean array of 2^p cells, b[], and set b[j] to true if j is some symbol under the bitmask i. If the cell is already set to true, then you don't have a unique representation.
Take the minimum number of LEDs needed across all unique representations, and output it.
有许多点创新:
1 读入时顺便把二进制转为了十进制
2 (1<<P) 等效于 2^P
3 避免O(N^2)的比较,事先建立bool空间来记录已访问的值
4 用位于运算和右移来计算一个十进制转为二进制后,该数含有多少位1
5 相比于第一种解法,无需特别的用subset()方法产生全排列,直接增量遍历就行了
事实证明,多次使用memset,memcpy,strcpy,strcmp等方法均会严重使运行速度降低
#define RUN #ifdef RUN #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <vector> #include <list> #include <cctype> #include <algorithm> #include <utility> #include <math.h> #include <ctime> using namespace std; #define MAXN 110 int P; // Number of LEDs, eg:7 列数,最大15 int N; // Number of symbols, eg:10 行数,最大100 int buf[105]; // 存储输入序列,转为了十进制的形式 int tmp[105]; // buf的复制 int myset[16]; // 排列 bool b[(1<<16)]; int minOnes; void play(){ // 2^P-1 int bound = (1 << P) - 1; int i, j; for(i=0; i<=bound; ++i){ memset(b, false, sizeof(b)); for(j=0; j<N; ++j){ int val = buf[j] & i; //cout << "val:" << val << endl; if(b[val]){ break; } else{ b[val] = true; } } //cout << "j:" << j << endl; if(j == N){ //cout << "j==N" << endl; //计算i的二进制数里含有1的个数 int ones = 0; int bit = i; while(bit > 0){ if(bit & 1){ ++ones; } bit = bit >> 1; } //cout << "ones:" << ones << endl; if(ones < minOnes){ minOnes = ones; } } } } int main(){ #ifndef ONLINE_JUDGE freopen("11205.in", "r", stdin); freopen("out.out", "w", stdout); #endif int cnt; cin >> cnt; while(cnt--){ memset(b, false, sizeof(b)); memset(buf, 0, sizeof(buf)); cin >> P >> N; for(int i=0; i<N; i++){ for(int j=0; j<P; j++){ int input; cin >> input; //从左至右存储为十进制 if(input) buf[i] += (input << j); //cout << input << " "; } //cout << endl; //cout << "---" << buf[i] << endl; } minOnes = P; play(); printf("%d\n", minOnes); } } #endif
相关推荐
经典的Android项目——bagilevi-android-pedometer.zip
React型计步器对iOS 8.0及更高版本的React Native计步器支持。 该模块是CMPedometer包装器。 有关CMPedometer的更多信息, 参见安装首先从您的应用程序目录安装npm软件包: npm install ...基本用法// Import the reac
安卓开发-开源项目pedometer .zip
入门npm install react-native-pedometer --save 在XCode的项目导航器中,右键单击“ Libraries ➜ Add Files to [your project's name] 转到node_modules react-native-pedometer/ios reactNativePedometer....
pedometer-master2
源码参考,欢迎下载
Pedometer 手机计步器
import Pedometer , { StepCounterEvent , SingleStepCounterEvent } from 'react-native-pedometer-android' ;if ( Pedometer . isSupported ( ) ) { const pedometerEvents = new NativeEventEmitter ( ...
Matlab-开源-计步器-算法 带有样本测试向量的计步器算法示例
The Privacy Friendly Pedometer stores the user's step count per hour. The user can review the recorded steps in a daily, weekly and monthly report. These reports also display the calculated distance ...
Wearable-Pedometer open source Wearable Pedometer base on nRF51822-AK 计步器 pedometer 目的 实现一个开源的计步器,尽量采用已有的硬件和软件,最大限度的提高简便性。让这个项目不再成为少数高手的玩具。 ...
##目录#### Introduction ##该项目包括Pedometer android应用程序(可跟踪您的步伐,计算速度和卡路里等)和一个web应用程序,该应用程序是一个单页应用程序仪表板,您可以在其中找到数据的图形化图表说明。...
计步器 探索React Native的原生方面。
Android开源项目pedometer-.zip
一个简单,轻量的计步器app,使用硬件传感器计算步数,而且对电池的消耗非常小。
Wearable computing devices can range providing very specific, limited features like heart rate monitoring and pedometer capabilities to advanced “smart” functions and features similar to those a ...
一个简单,轻量的计步器app,使用硬件传感器计算步数,而且对电池的消耗非常小。对学习计步功能而言是不错的项目。
runtastic_Pedometer是一个锻炼身体的软件
利用手机内置计步传感器,实时读取步数,并建立数据库,隔天清零