Codeforces 459C Pashmak and Buses (k进制状态压缩模拟)

Codeforces 459C Pashmak and Buses (k进制状态压缩模拟)

题意

有n个小朋友,k辆车,出去玩d天,要求任意两个小朋友不能每天都坐同一辆车,求乘车方案。

思路

看了题解。本来我是想模拟前k个小朋友都每天坐固定的车,然后后面的小朋友做个循环不断改变1-k的排列顺序但是后面wa在test3就很丢人,仔细一想不对,全排列这么多组合,我没必要都按顺序来循环啊(比如123 231 312这样,小数据下确实能保证坐的车都不一样,但是一旦小朋友多了,就会发现123 231 312 123 开始重复了,我直接输出-1其实不合适),然后就自闭了。看了题解恍然大悟。

其实从列的角度看,要求任意两个小朋友不能每天都坐同一班车,其实就是要求两列的排列不能完全相同。那么我们把一列转过来,每个位置都只能填入1-k的数字,就很像一个k进制数了,要求两列的状态不能完全一样,就是说两列的k进制表示的数值不能完全一样,一共有n个小朋友就是有n列,那只要找到n个不同的数转换为k进制,就是我们要的答案。因为有d天,就是有d行,每列就是一个d位k进制数,能表示的数值用十进制说就是从0到 k d − 1 {k^d - 1} kd1,那么只要保证 k d ≥ n {k^d \ge n} kdn即可。但是要注意的是这个k的数值很坑,随随便便就要溢出。。。

代码

#include <iostream>
#include <cstring>

using namespace std;
long long power(long long a,long long b)//快速幂
{
    long long ans = 1,k = a;
    while(b>0)
    {
        if(b%2==1){
            ans *= k;
        }
        k *= k;
        b>>=1;
    }
    return ans;
}
long long bus[1005][1005];
int main() {
    long long n,k,d;
    cin>>n>>k>>d;
    long long temper=power(k,d);
    if(k<n && (temper>0 && temper<n))//如果溢出了那肯定可以啊,n最大才1000
    {
        cout<<"-1"<<endl;
        return 0;
    }
    memset(bus,0,sizeof bus);
    for(long long i=0;i<n;i++)
    {
        long long temp=i;
        long long j=0;
        while(temp>0)
        {
            bus[j++][i]=temp%k;//转k进制数
            temp/=k;
        }
    }
    for(long long i=0;i<d;i++)
    {
        for(long long j=0;j<n;j++)
        {
            cout<<bus[i][j]+1<<" ";//bus的编号从1开始,所以要加1
        }
        cout<<endl;
    }
    
    return 0;
}

参考了以下博主,在此表示感谢:

http://www.voidcn.com/article/p-zowmoigw-bkm.html

https://blog.csdn.net/alps1992/article/details/42131581(快速幂参考了他的)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值