题目连接:http://codeforces.com/contest/459/problem/C
题目大意:
n个人,坐k辆车,一共坐d天,需要满足任意两个人不是每一天都坐同一趟车。
分析:
题目说,任意两人,不能一直都坐同一辆车,我们以横坐标表示人,纵坐标表示天数。
可以看到,满足题意要求,也就是说在画的二维数组上:每一行都不能与其它任意行完全相同即可!
此时,我们可以再第一行全部写0(第一个人每一天都坐1号车),之后在下一行最后一位 + 1 ,表示第二个人前d-1天都坐1号车,最后一天坐2号车。
当然,这不是无限制的加下去的,因为车的数量有限,我们加到k-1的时候(表示坐第k辆车),就不能再继续加,此时需要向前一位“进位”,含义就是换倒数第二天坐不同的车。
模拟出来也就是:k进制的加法。
注意:
当k十分大的时候,如果k大于n,那么直接令k = n 即可,因为效果一样的。
AC Code:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1010
int f[N][N];
int n, k, d;
void Print() {
//打印每天情况
memset(f, 0, sizeof(f));
int t;
for (int i = 1; i < n; i++) {
t = 0; //t表示进位
for (int j = d - 1; j >= 0; j--) {
int num = f[i-1][j] + t ;
if(j==d-1) num++;
if (num >= k) {
f[i][j] = num - k;
t = 1;
} else {
f[i][j] = num;
t = 0;
}
}
}
for(int i=0;i<d;i++){
for(int j=0;j<n;j++){
printf("%d ",f[j][i]+1);
}printf("\n");
}
}
int main() {
freopen("in.txt", "r", stdin);
while (scanf("%d %d %d", &n, &k, &d) != EOF) {
if (k > n)
k = n;
int flag = 0;int nn = d;int kk = 1;
while (nn--) {
kk = kk * k;
if (kk >= n) {
flag = 1;
break;
}
}
if (flag)
Print();
else
printf("-1\n");
}
return 0;
}