Hungry Rabbit
Problem C. Hungry Rabbit
Input file: hungry.in
Output file: hungry.out
Time limit: 10 seconds
Memory limit: 512 megabytes
可怕的洪水在夏天不期而至,兔子王国遭遇了前所未有的饥荒,它们不得不去外面的森林里寻找食物。
为了简化起见,我们假设兔子王国中有 n 只兔子,编号为 1 − n。在救济粮到来之前的 m 天中,每天恰好有 k 只兔子需要去森林里寻找粮食。森林里居住着可怕的大灰狼,所幸兔子已经摸清了大灰狼捕食习惯,即狼们在每一天只会捕食特定编号的兔子。为了安全起见,兔子们需要保证每次出去觅食的 k 只兔子都不会被狼捕食。
由于每天出去捕食的兔子都不尽相同,它们为每一天定义了一个生疏度 pi ,即第 i 天出来寻找食物,但是第 i − 1天却没有出来觅食的兔子个数。规定第1天的生疏度为 0.
现在兔子们希望在保证安全的前提下,每天的生疏度不能超过l,请为兔子们构造一个合法的方案。
Input
第一行包括四个整数 n, m, k 和l.
接下来n行,每行一个长度为m的01串。其中第i 行第j 个字符若为0,则表示狼在第j 天会捕食编号为 i 的兔子,为 1则表示不捕食。
Output
m 行,每行 k 个 1 − n 之间互不相同的整数,代表这一天出去寻找食物的兔子编号。如果没有合法方案,则输出一行−1即可。
Sample input.
5 4 3 1
1001
1101
1111
1110
0111
Sample output.
2 3 4
2 3 4
3 4 5
2 3 5
对于样例,在这4天中,出去觅食的兔子集合分别为 {2, 3, 4}, {2, 3, 4}, {3, 4, 5}, {2, 3, 5}.
• 对于 20%的测试数据,1 ≤ n,m ≤ 10
• 对于 100% 的测试数据,1 ≤ n,m ≤ 800, 1 ≤ k ≤ n, 1 ≤ l ≤ k
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int N=805; 6 int n,m,k,l; 7 int maxl[N][N],id[N]; 8 bool flag[N][N]; 9 int day; 10 inline bool cmp(const int &a, const int &b) { 11 return maxl[a][day]>maxl[b][day]; 12 } 13 int main() { 14 // freopen("hungry.in", "r", stdin); 15 // freopen("hungry.out", "w", stdout); 16 scanf("%d%d%d%d",&n,&m,&k,&l); 17 for(int i=1;i<=n;i++) { 18 char s[N]; 19 scanf("%s",s+1); 20 for(int j=m;j;j--) 21 if(s[j]=='0') 22 maxl[i][j]=0; 23 else 24 maxl[i][j]=maxl[i][j+1]+1; 25 id[i]=i; 26 } 27 day=1; 28 sort(id+1,id+n+1,cmp); 29 for(int i=1;i<=k;i++) 30 flag[day][id[i]]=1; 31 for(int i=2;i<=m;i++){ 32 for(int j=1;j<=n;j++) 33 flag[i][j]=flag[i-1][j]; 34 day=i; 35 sort(id+1,id+n+1,cmp); 36 int s=1,t=n; 37 for(int j=1;j<=l;j++) { 38 while(s<=n&&flag[i][id[s]]) 39 s++; 40 while(t&&!flag[i][id[t]]) 41 t--; 42 if(s>=t) 43 break; 44 flag[i][id[s]]=1; 45 flag[i][id[t]]=0; 46 } 47 for(int j=1;j<=n;j++) 48 if(flag[i][j]&&!maxl[j][i]) { 49 printf("-1"); 50 return 0; 51 } 52 } 53 for(int i=1;i<=m;i++,printf("\n")) 54 for(int j=1;j<=n;j++) 55 if(flag[i][j]) 56 printf("%d ",j); 57 return 0; 58 }