参考自点击打开链接
题目点击打开链接
四进制简介
编辑
四进制是以4为底数的进位制,以 0、1、2 和 3 四个数字表示任何实数。
四进制与所有固定底数的记数系统有着很多共同的属性,比如以标准的形式表示任何实数的能力(近乎独特),以及表示有理数与无理数的特性。有关属性的讨论可参考
十进制和
二进制,下面是十进制0至15与四进制与二进制的互换。
[1]
Qua
(四进)
|
Bin
(二进)
|
Dec
(十进)
|
---|---|---|
0
|
0000
|
0
|
1
|
0001
|
1
|
2
|
0010
|
2
|
3
|
0011
|
3
|
10
|
0100
|
4
|
11
|
0101
|
5
|
12
|
0110
|
6
|
13
|
0111
|
7
|
20
|
1000
|
8
|
21
|
1001
|
9
|
22
|
1010
|
10
|
23
|
1011
|
11
|
30
|
1100
|
12
|
31
|
1101
|
13
|
32
|
1110
|
14
|
33
|
1111
|
15
|
题意:
如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数。求L位K进制数中K好数的数目。
- 1
- 2
思路:
典型的动态规划题: 一位一位的去填充,用一个二维数组F[i][j]表示i位数以j结尾一共有多少种,接下来要放下一位的话,只要判断要放的这位数字是否是j的邻位即可。
好好理解,
#include <algorithm> #include <cstring> #include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <map> #include <set> #include<cmath> using namespace std; const int maxn=105; const int mod=1000000007; int f[maxn][maxn]; int main(){ int L,k; long long ans,n; int cnt=0; int sum=0; while(cin>>k>>L){ if(L==1)//如果只是一位数 { cout<<k-1<<endl; continue; } else{ memset(f,0,sizeof(f)); for(int j=0;j<k;j++){ f[1][j]=1;//每个小于k的数是1个 } for(int i=2;i<L;i++){ for(int j=0;j<k;j++){ cnt=0; for(int r=0;r<k;r++){ if(r==j-1||r==j+1) continue;//若相邻,不计 cnt=(cnt+f[i-1][r])%mod; } f[i][j]=cnt; } } for(int j=1;j<k;j++){//两位数从1开始,确定第一位 cnt=0; for(int r=0;r<k;r++){ if(r==j-1||r==j+1) continue; //判断要放的j是否是已放好的i-1位数的最后每一位r的邻位 cnt=(cnt+f[L-1][r])%mod; //cnt的值即为其本身加上放好前i-1位且最后一位放的是r的个数, //因为前i-1位数放好后继续放下一位,此时的下一位必须是循环的这一个 } sum=(sum+cnt)%mod; } } cout<<sum<<endl; } return 0; }
一定理解题意,如题意中,2位4进制数,十位和个位数不相等