Codeforces Round #359 (Div. 2) C. Robbers' watch

Posted Kurokey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #359 (Div. 2) C. Robbers' watch相关的知识,希望对你有一定的参考价值。

题目链接:传送门

题目大意:有一只表,由7进制表示,你将一天分为n个小时,将一小时分为m分钟,要求表上显示的数字各不相同,问在n,m的限制下有多少种合法的时间表示

     例如 n=2,m=3 (0: 1), (0: 2), (1: 0), (1: 2).  n=8,m=2 (02: 1), (03: 1), (04: 1), (05: 1), (06: 1).

题目思路:因为是由7进制表示,所以手表上显示的数字不能超过7个,否则必然有重复的(不合法),因此我们只需要特判一下,然后dfs即可。

     这个题还是比较可惜的,当时晚上没做出来,早上起来发现边界情况有点问题,改了一下就过了,自己还是太弱。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 100005
#define maxn 1005
typedef pair<int,int> PII;
typedef long long LL;

int n,m,k,x,num,y;
int vis[10],ans;
void dfs2(int sum,int cnt){ ///dfs2处理分钟段(m),其他和dfs1同理
    if(sum>=m)return;
    if(cnt==y){++ans;return;}
    for(int i=0;i<7;++i){
        if(!vis[i]){
            vis[i]=1;
            sum=sum*7+i;
            dfs2(sum,cnt+1);
            sum=(sum-i)/7;
            vis[i]=0;
        }
    }
}
void dfs1(int sum,int cnt){///dfs1处理小时段(n),sum表示当前时间(sum<n),
    if(sum>=n)return ;     ///cnt表示已经处理了几位数字
    if(cnt==x){
        for(int j=0;j<7;++j)if(!vis[j]){
            vis[j]=1;
            dfs2(j,1);
            vis[j]=0;
        }
    }
    for(int i=0;i<7;++i){
        if(!vis[i]){
            vis[i]=1;
            sum=sum*7+i;
            dfs1(sum,cnt+1);
            sum=(sum-i)/7;
            vis[i]=0;
        }
    }
}
int deal(int x){    ///特殊处理,返回表示n,m需要多少位数字
    int cnt=0;
    while(x){
        ++cnt;
        x=x/7;
    }
    return cnt;
}
int main(){
    int i,j,group,v;
    scanf("%d%d",&n,&m);
    if(n%7==0)x=deal(n-1);///这里需要注意,如果n能被7整除
    else x=deal(n);       ///那么表示n所需要的数字位数要减一,也就是这没考虑清楚,很可惜。
    if(m%7==0)y=deal(m-1);///m同理处理
    else y=deal(m);
    if(x+y>7){exit(0*printf("0\n"));}
    for(i=0;i<7;++i){
        vis[i]=1;
        dfs1(i,1);
        vis[i]=0;
    }
    printf("%d\n",ans);
    return 0;
}

 

以上是关于Codeforces Round #359 (Div. 2) C. Robbers' watch的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #359 (Div. 2) D. Kay and Snowflake

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Prime Number(CodeForces-359C)[快速幂/思维]

Codeforces Round #726 (Div. 2) B. Bad Boy(贪心)

题解 CF359D