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
相关推荐
【文件名称列表】中的"bagilevi-android-pedometer-b27cac2"可能是该项目的一个特定版本标签或分支,这在版本控制系统如Git中常见。这表示你可以查看该版本的源代码,了解在某个时间点项目的状态。 在分析这个项目...
入门npm install react-native-pedometer --save 在XCode的项目导航器中,右键单击“ Libraries ➜ Add Files to [your project's name] 转到node_modules react-native-pedometer/ios reactNativePedometer....
React型计步器对iOS 8.0及更高版本的React Native计步器支持。 该模块是CMPedometer包装器。 有关CMPedometer的更多信息, 参见安装首先从您的应用程序目录安装npm软件包: npm install ...基本用法// Import the reac
Android安卓项目源码-开源项目pedometer.zip
《Android参考源码-开源项目pedometer》 在Android开发领域,开源项目是开发者们学习、借鉴和创新的重要资源。本项目"pedometer"是一个基于Android的计步器应用,它为我们提供了关于如何实现计步功能的源代码,是...
【安卓开发-开源项目pedometer】是一个专门为Android平台设计的计步器应用的源代码库。这个开源项目为开发者提供了一个实现步数检测和健康管理功能的参考实例。通过研究此项目,开发者可以学习如何在Android设备上...
标题 "pedometer-master2" 暗示这是一个与计步器相关的开源项目,可能是用于开发一个计步器应用或者库的源代码。描述中的信息较为简单,同样仅提及项目名称,没有提供具体的功能或用途。标签 "pedometer" 确认了该...
import Pedometer , { StepCounterEvent , SingleStepCounterEvent } from 'react-native-pedometer-android' ;if ( Pedometer . isSupported ( ) ) { const pedometerEvents = new NativeEventEmitter ( ...
Pedometer-master可能是一个开源项目,提供了计步器功能的源代码,开发者可以通过研究这个项目来学习如何利用手机传感器开发计步器应用,或者在此基础上进行二次开发,添加更多个性化的功能,比如社交分享、步数挑战...
在这个"React-Native-Pedometer-App"项目中,我们将深入探讨如何在React Native中集成iOS的计步器功能。 在iOS平台上,计步器功能通常通过Core Motion框架实现,这是一个原生的iOS API,提供了运动数据,包括步数、...
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应用程序,该应用程序是一个单页应用程序仪表板,您可以在其中找到数据的图形化图表说明。...
本项目“simple-pedometer-master”是一个基于Android Studio的计步器应用实例,旨在帮助开发者理解如何实现这样一个功能。 首先,我们要了解的是**Android Studio**,这是Google为Android开发提供的集成开发环境...
《计步器应用详解——基于Pedometer-Demo-Application》 计步器技术在现代健康监测领域扮演着重要角色,它能够精确记录用户的步数,帮助用户追踪运动量,从而促进健康生活方式。本文将围绕"Pedometer-Demo-...
一个简单,轻量的计步器app,使用硬件传感器计算步数,而且对电池的消耗非常小。
【Android开源项目pedometer】是一个专注于计步功能的开源应用,它为开发者提供了一个实现计步器功能的参考实现。这个项目主要适用于Android平台,旨在帮助开发者了解如何在移动设备上构建一个精确、高效的计步器...
本项目"计步器(Pedometer-master)"就是一个专注于实现这一功能的开源应用,适合开发者学习如何在Android平台上构建计步器功能。 1. **计步器原理**:计步器主要依赖于手机中的加速度传感器,该传感器能够检测设备在...