codeforce Pashmak and Buses(dfs枚举)

/*
   题意:n个同学,k个车, 取旅游d天!
   要求所有的学生没有两个或者两个以上的在同一辆车上共同带d天! 输出可行的方案!

   对于d行n列的矩阵,第i行第j列表示的是第i天第j个同学所在的车号!
   也就是保证所有行不全相同,即每一列都是不相同的!
   如果每一列都不相同就是表示第j个同学(第j列)在这d天中不会和其他同学(列)在这d天中 都在同一辆车中! 

   思路:对于每一列我们枚举d天该学生所在的车号!它的下一列只保证有一个元素和它不同就行了!依次下去!

   还有一共有 d 个位置来填充车号(1....k)!每一个位置的数字都可以是(1...k)中的一个数字。
   总共的枚举次数为 k^d, 一共有n个同学,枚举n次就可以了,所以有 k^d >=n才有解!
*/
#include<iostream>
#include<cstdio>
using namespace std;

int ret[1005][1005];
int a[1005];
int n, k, d;
int cnt;
bool dfs(int cur){
   if(cur>d){
        ++cnt;
        for(int i=1; i<=d; ++i)
       ret[i][cnt]=a[i];
        if(cnt==n)
          return true;
     return false;
   }
   for(int i=1; i<=k; ++i){
       a[cur]=i;
       if(dfs(cur+1))//强力剪枝....搜索完成后不在进行搜索!
          return true;
   }
   return false;
}

int main(){
   while(scanf("%d%d%d", &n, &k, &d)!=EOF){
          cnt=0;
          int kk=k;
          bool flag=false;
          for(int i=1; i<=d; ++i){//保证k^d>=n才可能有解!
                if(kk>=n){
              flag=true;
              break;
          }
          kk*=k;
       }
       if(flag){
           dfs(1);
           for(int i=1; i<=d; ++i){
              for(int j=1; j<=n; ++j){
                 printf("%d", ret[i][j]);
                 if(j!=n)  printf(" ");
              }
              printf("\n");
           }
       }
       else printf("-1\n");
   }
   return 0;
}
时间: 2024-09-19 12:50:44

codeforce Pashmak and Buses(dfs枚举)的相关文章

UVa 10717 Mint:DFS枚举4个数的lcm

10717 - Mint Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=1658 The Royal Canadian Mint has commissioned a new series of designer coffee tables, with l

poj 1950 Dessert(dfs枚举,模拟运算过程)

/* 这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值! 如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值(这种方法见第二个代码),直到最后,这样不必每一次枚举都要从头再算一遍值! */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; char ch[20]; char sign[3]={

topcoder 2C 1000 WellTimedSearch dfs+枚举

          首先上题解的传送门.        这个关键就是求出个f(x,A)也就是x结点在A层所需要的额外点数.我们所要求的就是枚举x,然后判断A-B层中的节点数,取最大值除以N即是我们要求的最大概率        求解f(x,A)时直接dfs,因为f(1,1)=1 ,f(x,A)=ceil(x/2) + f(ceil(x/2), A-1)  题解: int getLesser(int A, int x) { if (x == 1) { // cut execution time, i

hdu4751Divide Groups(dfs枚举完全图集合或者bfs染色)

/************************************************************************* > File Name: j.cpp > Author: HJZ > Mail: 2570230521@qq.com > Created Time: 2014年08月28日 星期四 12时26分13秒 *******************************************************************

HDU 2489 Minimal Ratio Tree (DFS枚举+最小生成树Prim)

链接: HDU : http://acm.hdu.edu.cn/showproblem.php?pid=2489 POJ  : http://poj.org/problem?id=3925 题目: Problem Description For a tree, which nodes and edges are all weighted, the ratio of it is calculated according to the following equation. Given a comp

codeforce No to Palindromes!(枚举)

/* 题意:给定一个字符串中没有任何长度>1的回文子串!求按照字典序的该串的下一个字符串 也不包含长度>1的任何回文子串! 思路:从最低位进行枚举,保证第i位 不与 第 i-1位和第 i-2位相同就好了!那么因为前边i-1 位没有长度>1的回文子串,那么前i位也不会出现!最后将最后边的字符按照相同的原则补齐就好了! */ #include<iostream> #include<cstdio> #include<cstring> #include<

算法:poj 3140 Contestants Division(树形dp? dfs计数+枚举)

题目 给n个节点的带权树,删掉其中一边,就会变成两颗子树, 求删去某条边使得这这两颗子树的 权值之差的绝对值最小. 思路 直接dfs一次,计算所有子树的权值总和tot[i] 如果删掉一条边 (v, fa),fa是v的父亲节点, 那么v子树权值总和为tot[v],显然另一棵子树的权值总和就是sum-tot[v] , 最总取最小绝对值即可. 这题要注意用long long 其实就是dfs+枚举,想不通为什么有人会 把这题列为树形dp? 代码 /**==========================

codeforces B - Preparing Olympiad(dfs或者状态压缩枚举)

B. Preparing Olympiad You have n problems. You have estimated the difficulty of the i-th one as integer ci. Now you want to prepare a problemset for a contest, using some of the problems you've made. A problemset for the contest must consist of at le

UVa 10616 Divisible Group Sums:DFS以及DP

10616 - Divisible Group Sums Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=1557 思路:用DFS+记忆化搜索枚举组合,注意数字有<0的. return dp[i][cnt][sum] = f(i + 1, cnt +