大体题意:
给你一个n*m的0-1矩阵(n,m <= 400),它的第一列固定不动,其他列你可以随意交换。你要使每行的1都连续地出现。求出这样的方案。保证答案唯一!
思路:
因为保证了答案唯一,所有正解只有一个,因此不合法的情况会有很多,因此我们可以考虑 搜索 + 剪枝的方案。
矩阵只有0 和1 因此一个位置要么填0要么填1,这两种方式都考虑到剪枝就可以很轻松的过了!
最先想到的肯定是枚举列,在枚举每一行检测是否合法!
剪枝方法:
如果这一列这一个位置是1的话,那么前面的一个位置也必须是1,否则就不连续了!
如果这一列这一个位置是0的话 并且 前面出现了1,那么后面肯定不能有1了,否则就被0隔开了! 因此可以检测前面1的个数是否等于这一行所有1的个数。
这两种剪枝,后一种比较厉害。
两种都考虑就好了!63ms就可以过了
详细见代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 400 + 7;
char s[maxn][maxn];
int a[maxn][maxn];
int ans[maxn];
int vis[maxn], one[maxn], sum[maxn];
int n, m;
int all = 0;
void dfs(int c){
if (all)return;
if (c == m){
all = 1;
return;
}
for (int i = 1; i < m; ++i){
if (vis[i] == 0){
bool ok = 1;
for (int j = 0; j < n; ++j){
if (a[j][i] == 1){
if (one[j] && a[j][ans[c-1]] == 0){
ok = 0;
break;
}
}else {
if (one[j] && one[j] < sum[j]){
ok= 0;
break;
}
}
}
if (!ok)continue;
vis[i] = 1;
for (int j = 0; j < n; ++j){
one[j] += a[j][i];
}
if (!all)ans[c] = i;
dfs(c+1);
vis[i] = 0;
for (int j = 0; j < n; ++j){
one[j] -= a[j][i];
}
}
}
}
int main(){
scanf("%d %d",&n, &m);
memset(vis,0,sizeof vis);
vis[0] = 1;
for (int i = 0; i < n; ++i){
scanf("%s",s[i]);
if (s[i][0] == '1')one[i]++;
for (int j = 0; s[i][j]; ++j){
if (s[i][j] == '1')a[i][j] = 1;
else a[i][j] = 0;
sum[i] += a[i][j];
}
}
dfs(1);
for (int i = 0; i < m; ++i) printf("%d\n",ans[i]);
return 0;
}
Consecutive ones
Description 11111111000000000000 00000000000000001111 00000000000011000000 00000000000000111100 00000000000001110000 00111000000000000000 00000000000111000000 00000000111100000000 00000000000000000001 11000000000000000000 00001111111000000000 00000111111111111111 00000000011111100000 00000000001111111110 00000000000000011110 00000001111100000000 00000011111111110000 00011110000000000000 01111111111100000000 00000000000000000111 A time schedule is represented by a 0-1 matrix with n lines and m columns. Each line represents a person and each column an event. All the persons participating to an event have a one in the corresponding entry of their line. Persons not attending the event have a zero entry in that column. Events occur consecutively. Problem Problem Write a program that finds a smart permutation of the events where each person attends all its events in a row. In other words, permute the columns of the matrix so that all ones are consecutive in each line. Input
The first line of the input consists in the number n<=400 of lines. The second line contains m<=400 , the number of columns. Then comes the n lines of the matrix. Each line consists in m characters `0' or `1'.
The input matrix is chosen so that there exists only one smart permutation which preserves column 0 in position 0. To make things easier, any two columns share few common one entries. Output
The output consists of m numbers indicating the smart permutation of the columns. The first number must be 0 as column 0 does not move. The second number indicate the index (in the input matrix) of the second column, and so on.
Sample Input 3 4 0110 0001 1101 Sample Output 0 3 1 2 Hint
Sample input2
6 5 01010 01000 10101 10100 00011 00101 Sample output2 0 2 4 3 1 Sample input3 21 20 00101000000000000000 10010010010110010100 00101101000000000000 01000000000000001000 00000101100000100000 01000000100000100000 00000010000110000000 01000000000001001000 00000000001001000011 00001000000000000000 10000000000000000100 00010010011000010011 01111101111001111011 01000000000001101011 01100101100001101001 00100101100000000000 00010000001001000011 01010000101001111011 00000010010010010000 00010010011111010111 00101001000000000000 Sample output3 0 17 11 12 6 9 15 3 10 18 19 13 16 1 14 8 5 7 2 4 Source |
[Submit] [Go Back] [Status] [Discuss]