欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-09 13:09:18
...

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到kd1{k^d - 1},那么只要保证kdn{k^d \ge n}即可。但是要注意的是这个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(快速幂参考了他的)

相关标签: 数论

上一篇: windows 下 babun 配置

下一篇: py笔记