hihocoder第220周-一道拧巴的题
一、220周
问题描述
键盘上有N个数字按键,每个按键只能按一次,每次可以按下多个键,请输出所有可能的按键情况。
输入一个整数N(N在1~8之间),输出全部的按键可能。例如:输入3,输出为
1-2-3
1-23
1-3-2
12-3
123
13-2
2-1-3
2-13
2-3-1
23-1
3-1-2
3-12
3-2-1
输出按照字符串大小从小到大输出。
思路
对于给定数组a,a中存放着备用数字,从a中分别取1,2,3,...len(a)个元素组成一组group。然后a-group=b,将b数组递归向后传递。
Java里面的迭代器比较难受,写出来的代码也拧巴,这点非常考验代码能力,是一道非常不错的面试题。
Python里面的生成器更简便。
代码
import sun.reflect.generics.tree.Tree;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
TreeSet<String> a = new TreeSet<>();
class SelectCount implements Iterator<String> {
int[] a;
int cnt;
int[] p;
boolean over = true;
SelectCount(int[] a, int cnt) {
this.a = a;
this.cnt = cnt;
p = new int[cnt];
for (int i = 0; i < cnt; i++) {
p[i] = i;
}
}
@Override
public boolean hasNext() {
return over;
}
void move() {
for (int i = cnt - 1; i >= 0; i--) {
if (p[i] != a.length - cnt + i) {
p[i]++;
for (int j = i + 1; j < cnt; j++) {
p[j] = p[j - 1] + 1;
}
return;
}
}
over = false;
}
@Override
public String next() {
String ans = Arrays.stream(p).map(x -> a[x]).mapToObj(x -> x + "").collect(Collectors.joining());
move();
return ans;
}
}
void go(int[] a, LinkedList<String> l) {
// System.out.println(Arrays.stream(a).mapToObj(x -> x + "").collect(Collectors.joining()));
if (a.length == 0) {
this.a.add(l.stream().collect(Collectors.joining("-")));
return;
}
for (int i = 1; i <= a.length; i++) {
SelectCount sel = new SelectCount(a, i);
while (sel.hasNext()) {
String s = sel.next();
int[] b = new int[a.length - i];
int bi = 0;
//a数组减去b数组
for (int j = 0; j < a.length; j++) {
if (!s.contains(a[j] + "")) {
b[bi++] = a[j];
}
}
l.add(s);
go(b, l);
l.removeLast();
}
}
}
Main() {
Scanner cin = new Scanner(System.in);
int N = cin.nextInt();
int[] a = new int[N];
for (int i = 1; i <= N; i++) {
a[i - 1] = i;
}
go(a, new LinkedList<>());
for (String i : this.a) {
System.out.println(i);
}
}
public static void main(String[] args) {
new Main();
}
}
二、221周
题目链接
还是上面那样的题干,问题变成一道组合计数题,问一共有多少种按法。
枚举第一次按下的情况,剩下的情况递归解决,递归时可以利用DP加速,不加速肯定超时。计算组合数时,必须使用杨辉三角,否则太慢。使用编程语言时,必须用C/C++,连Java都会超时,这个超时当然是运行效率了。
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
int mod = 1000000007;
typedef long long ll;
ll c[1007][1007];
void init() {
memset(c, 0, sizeof(c));
for (int i = 0; i < 1007; i++)c[i][0] = 1;
c[0][0] = 1;
for (int i = 1; i < 1007; i++) {
for (int j = 1; j <= i; j++) {
c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
c[i][j] %= mod;
}
}
}
ll dp[1007];
ll solve(int N) {
if (N == 1 || N == 0)return 1;
if (dp[N] != -1)return dp[N];
ll s = 0;
for (int i = 1; i <= N; i++) {
s += c[N][i]%mod * solve(N - i)%mod;
s %= mod;
}
dp[N] = s;
return s;
}
int main() {
int N;
cin >> N;
init();
memset(dp, -1, sizeof(dp));
cout << solve(N);
return 0;
}
hihocoder第220周-一道拧巴的题的更多相关文章
- hihoCoder 第136周 优化延迟(二分答案+手写堆)
题目1 : 优化延迟 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho编写了一个处理数据包的程序.程序的输入是一个包含N个数据包的序列.每个数据包根据其重要程度不同 ...
- HihoCoder第三周与POJ2406:KMP算法总结
HihoCoder第三周: 输入 第一行一个整数N,表示测试数据组数. 接下来的N*2行,每两行表示一个测试数据.在每一个测试数据中,第一行为模式串,由不超过10^4个大写字母组成,第二行为原串,由不 ...
- 洛谷P2918 [USACO08NOV]买干草(一道完全背包模板题)
题目链接 很明显的一道完全背包板子题,做法也很简单,就是要注意 这里你可以买比所需多的干草,只要达到数量就行了 状态转移方程:dp[j]=min(dp[j],dp[j-m[i]]+c[i]) 代码如下 ...
- 又一道区间DP的题 -- P3146 [USACO16OPEN]248
https://www.luogu.org/problemnew/show/P3146 一道区间dp的题,以区间长度为阶段; 但由于要处理相邻的问题,就变得有点麻烦; 最开始想了一个我知道有漏洞的方程 ...
- [真题] 一道 vsftp 运维题
一道 vsftp 运维题 一.前言 在 V 站上凑巧看到了好友发的求助帖,五天时间一个理他的都没有.哈哈哈~ 废话不多说,我们来试试. 二.题目 这里我们假设存在这样的场景: 网络内有普通用户 ade ...
- QDUOJ 一道简单的数据结构题 栈的使用(括号配对)
一道简单的数据结构题 发布时间: 2017年6月3日 18:46 最后更新: 2017年6月3日 18:51 时间限制: 1000ms 内存限制: 128M 描述 如果插入“+”和“1”到 ...
- hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)
http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...
- hihocoder第42周 k*N骨牌覆盖(状态dp+矩阵快速幂)
上周的3*N的骨牌,因为状态只有8中,所以我们可以手算出状态转移的矩阵 但是这周是k*N,状态矩阵不好手算,都是我们改成用程序自动生成一个状态转移的矩阵就行了,然后用这个矩阵进行快速幂即可 枚举枚举上 ...
- 【hihoCoder 第133周】2-SAT·hihoCoder音乐节
http://hihocoder.com/contest/hiho133/problem/1 2-sat模板...详细的题解请看题目里的提示. tarjan模板打错again致命伤qwq #inclu ...
随机推荐
- 在springboot项目中使用mybatis 集成 Sharding-JDBC
前段时间写了篇如何使用Sharding-JDBC进行分库分表的例子,相信能够感受到Sharding-JDBC的强大了,而且使用配置都非常干净.官方支持的功能还包括读写分离.分布式主键.强制路由等.这里 ...
- Neo4j资料 Neo4j教程 Neo4j视频教程 Neo4j 图数据库视频教程
课程发布地址 地址: 腾讯课堂<Neo4j 图数据库视频教程> https://ke.qq.com/course/327374?tuin=442d3e14 作者 庞国明,<Neo4j ...
- Java方法containsAll学习
有时候我们需要判断B链表是不是A链表的子集,我们可以使用A.containsAll(B)来判断,当返回值是true的时候就表明B链表是A链表的子集,当返回值是false时候就表明B链表不是A链表的子集 ...
- Android -- DiskLruCache
DiskLruCache 创建一个磁盘缓存对象: public static DiskLruCache open(File directory, int appVersion, int valueCo ...
- 调试工具DebugView
可以用来跟踪如下函数的输出: Win32 OutputDebugString Kernel-mode DbgPrint All kernel-mode variants of DbgPrint i ...
- LINUX 查找tomcat日志关键词
#查询catalina.out日志文件中的关键词为2016-04-13 11:26:00的日志信息 grep -C 10 '2016-04-13 11:26:00' catalina.out |mor ...
- php获取当前时间的方法
1.获取当前时间 date('Y-m-d H:i:s', time()) 2.字符串转时间 date('Y-m-d H:i:s',strtotime('2018-8-21 22:00:00'))
- IO multiplexing 与 非阻塞网络编程
使用I/O multipexing 的网络编程中,一般需要采用非阻塞网络编程的风格,防止服务端在处理高连接量大时候阻塞在某个文件描述符上面,比如某个socket 有大量的数据需要写,但是内核发送缓冲区 ...
- Word2007视频教程
超级好教程 http://v.youku.com/v_show/id_XMTAwOTgwNTIw.html 视频: oeasy教你玩转office系列之Word视频教程01 http://v.youk ...
- Unbuntu和Centos中部署同时多版本PHP的详细过程
镜像制作:Unbuntu14 部署LAMP过程 1.Azure经典版中创建源Ubuntu14,并使用Xshell连接,并切换到root帐户下. 2.安装php5.4,新建/var/local/ ...