[BZOJ 1081] [SCOI2005] 超级格雷码 【找规律】

题目链接:BZOJ - 1081

备注:此题BZOJ上貌似没有 spj ,要把一般顺序的每个格雷码倒着输出...比如 0102 输出为 2010

题目分析

就是按照 Gray 码的生成方法写前几个出来找找规律就好了。

生成方法:以 3 位 3 进制为例

0 0 0

0 0 1

0 0 2

0 1 2 //中位写 1 ,后面镜像复制

0 1 1

0 1 0

0 2 0 //中位写 2,后面镜像复制

0 2 1

0 2 2

1 2 2 //高位写 1 ,后面镜像复制

1 2 1

........

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

const int MaxN = 20 + 5;

int n, m, Tot;
int Pow[MaxN];

void PrintCh(int x) {
	if (x < 10) printf("%d", x);
	else printf("%c", ‘A‘ + x - 10);
} 

int main()
{
	scanf("%d%d", &n, &m);
	Pow[0] = 1;
	for (int i = 1; i <= n; ++i) Pow[i] = Pow[i - 1] * m;
	Tot = Pow[n];
	int x, y;
	for (int i = 0; i < Tot; ++i) {
		for (int j = n - 1; j >= 0; --j) {
			x = i / Pow[n - j];
			y = (i / Pow[n - j - 1]) % m;
			if (x & 1) PrintCh(m - y - 1);
			else PrintCh(y);
		}
		printf("\n");
	}
	return 0;
}

  

时间: 2024-10-13 00:53:17

[BZOJ 1081] [SCOI2005] 超级格雷码 【找规律】的相关文章

bzoj1081 [SCOI2005]超级格雷码

Description 著名的格雷码是指2n个不同n位二进制数(即0~2n-1,不足n位在前补零)的一个排列,这个排列满足相邻的两个二进制数的n位数字中最多只有一个数字不同(例如003和001就有一个数位不同,而003和030有两个数位不同,不符合条件).例如n=2时,(00,01,11,10)就是一个满足条件的格雷码. 所谓超级格雷码就是指Bn个不同的n位B进制数的排列满足上面的条件. 任务:给出n和B(2≤B≤36, 1≤Bn≤65535),求一个满足条件的格雷码.对于大于9的数位用A~Z表

BZOJ1081超级格雷码

著名的格雷码是指2n个不同n位二进制数(即0~2n-1,不足n位在前补零)的一个排列,这个排列满足相邻的两个二进制数的n位数字中最多只有一个数字不同(例如003和001就有一个数位不同,而003和030有两个数位不同,不符合条件).例如n=2时,(00,01,11,10)就是一个满足条件的格雷码. 所谓超级格雷码就是指Bn个不同的n位B进制数的排列满足上面的条件. 任务:给出n和B(2≤B≤36, 1≤Bn≤65535),求一个满足条件的格雷码.对于大于9的数位用A~Z表示(10~35). 题解

BZOJ 1228 E&amp;G(sg函数+找规律)

把一对石子堆看出一个子游戏.打出子游戏的sg表找规律.. 这个规律我是一定找不出来的... 对于i,j,如果 (i-1)%pow(2,k+1) < pow(2,k) (j-1)%pow(2,k+1) < pow(2,k) 那么最小的k值就是sg值. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector

BZOJ 1002 FJOI 2007 轮状病毒 暴力+找规律+高精度

题目大意: 思路:基尔霍夫矩阵求生成树个数,不会. 但是可以暴力打表.(我才不会说我调试force调试了20分钟... CODE(force.cc): #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000 using namespace std; struct Edge{ int x,y; Edge(int _,int __

bzoj 1002 [FJOI2007]轮状病毒——打表找规律

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1002 看 Zinn 的博客:https://www.cnblogs.com/Zinn/p/9252831.html 时隔六个月,自己终于也 A 了这道题. #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define db double using name

[bzoj1081]超级格雷码

手动模拟一组样例,可以理解大致应该如何操作具体实现中,记录每一位当前应该+1还是-1,然后操作最低的位并将后面的+1和-1全部取反即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,b,a[105],flag[105]; 4 void write(){ 5 for(int i=1;i<=n;i++) 6 if (a[i]<10)printf("%d",a[i]); 7 else printf(&

bzoj 1002 [FJOI2007]轮状病毒 高精度&amp;&amp;找规律&amp;&amp;基尔霍夫矩阵

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2234  Solved: 1227[Submit][Status] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 HINT Source 基尔霍夫矩阵总算编出来了,这道题考

LeetCode 格雷码序列的生成

问题概述:在一组数的编码中,若随意两个相邻的代码仅仅有一位二进制数不同.则称这样的编码为格雷码. 2位数的格雷码序列:00 : 001 : 111 : 310 : 2找规律:假设要求n位的格雷码,先要求出n-1位的格雷码. 循环上一次格雷码的每一位,都会生成两个新的格雷码: 统计'1'出现的次数假设为偶数: 两个新格雷码分别为xxx1和xxx0假设为奇数: 两个新格雷码分别为xxx0和xxx1 以3位格雷码为例: 由00得:000 = 00+(0)001 = 00+(1) 由01得:011 =

CSP-S 2019 格雷码

\(\text{格雷码}\) 现在给出\(n, k\)请你求出按上述算法生成的\(n\)位格雷码中的\(k\)号二进制串. std1 \(\text{期望得分 100pts}\) 考场上通过找规律发现是循环往复做的 所以用记忆化搜索获取每个数的格雷码 时间复杂度不会证明 代码如下 inline int calc (int x) { for (int i = 0; i < 64; i ++ ) { if ((1ull << i) > x) return (1ull <<