【COGS 56】质数取石子
【问题描述】
当 DD 确定会取得胜利时,他会说:“不管 MM 选择怎样的取石子策略,我都能保证至多 X 步以后就能取得胜利。”那么,最小的满足要求的 X 是多少呢?注意,不管是 DD 取一次石子还是 MM 取一次石子都应该被计算为“一步”。
【输入格式】
【输出格式】
【样例输入】
3
8
9
16
【样例输出】
1
-1
3
【样例说明】
当桌上有 16 个石子时,DD 可以保证在 3 步以内取得胜利。可以证明,为了在 3 步内取得胜利,DD 第一步必须取 7 个石子。剩下 9 个石子之后,不管第二步 MM 怎么取,DD 取了第三步以后可以保证胜利,所以输出 3。
【数据范围】
【分析】
动态规划。
首先打出素数表,用v[i]来保存DD有i颗石子的时候是否可以胜利,1代表可以,0代表不可以。
v[i]通过前面的状态可以计算出来,如果v[i-p](p为素数)为false,显然v[i]就应该为1,因为多取了一次。
然后对于不同的v[i]状态分情况讨论,
f[i]=min{f[i-prime[j]]}(v[i]=1)计算可能获胜时最少的步数
f[i]=max{f[i-prime[j]]}(v[i]=0)计算不可能获胜时最多的步数
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#define LOCAL
const int maxn=+;
using namespace std;
int prime[maxn];
int flag[maxn],f[maxn];
int v[maxn]; void prepare(); int main(){
int T,n;
#ifdef LOCAL
freopen("data.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
prepare();//打表
scanf("%d",&T);
while (T--){
scanf("%d",&n);
if (v[n]) printf("%d\n",f[n]);
else printf("-1\n");
}
return ;
}
void prepare(){
prime[]=;
for (int i=;i<=;i++){
int g=;
for (int j=;j<=prime[];j++){
if (i%prime[j]==){
g=;
break;
}
}
//增加新的质数
if (g) prime[++prime[]]=i;
flag[i]=prime[];
}
memset(v,,sizeof(v));
memset(f,,sizeof(f));
for (int i=;i<=;i++){
for (int j=flag[i];j>=;j--)
if (!v[i-prime[j]]){
v[i]=;
break;
}
//printf("%d\n",v[i]);
}
int tmp=;
for (int i=;i<=;i++){
if (v[i]){
tmp=;
for (int j=flag[i];j>=;j--)
if (!v[i-prime[j]]) tmp=min(tmp,f[i-prime[j]]);
}
else {
tmp=-;
for (int j=flag[i];j>=;j--)
tmp=max(tmp,f[i-prime[j]]);
}
f[i]=tmp+;
}
return;
}
【COGS 56】质数取石子的更多相关文章
- Cogs 56. 质数取石子(博弈)
质数取石子 ★★ 输入文件:stonegame.in 输出文件:stonegame.out 简单对比 时间限制:1 s 内存限制:128 MB 问题描述 DD 和 MM 正在玩取石子游戏.他们的游戏规 ...
- P1857 质数取石子 (DP,递推)
题目描述 桌上有若干个石子,每次可以取质数个.谁先取不了,谁就输.问最少几步能赢?(一个人取一次算一步) 输入输出格式 输入格式: 第一行N,表示有N组数据 接下来N行为石子数 输出格式: 每组数据一 ...
- 洛谷 P4018 Roy&October之取石子
洛谷 P4018 Roy&October之取石子 题目背景 Roy和October两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有n个石子,两人每次都只能取 p^kpk 个(p为质 ...
- 洛谷 P4706 取石子 解题报告
P4706 取石子 题目描述 现在 Yopilla 和 yww 要开始玩游戏! 他们在一条直线上标记了 \(n\) 个点,从左往右依次标号为 \(1, 2, ..., n\) .然后在每个点上放置一些 ...
- 洛谷 Roy&October之取石子
题目背景 Roy和October两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有n个石子,两人每次都只能取pk 个(p为质数,k为自然数,且pk小于等于当前剩余石子数),谁取走最后一个石子 ...
- 洛谷——P4018 Roy&October之取石子
P4018 Roy&October之取石子 题目背景 Roy和October两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有n个石子,两人每次都只能取p^kpk个(p为质数,k为自 ...
- P4018 Roy&October之取石子
题目背景 Roy和October两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有n个石子,两人每次都只能取 p^kpk 个(p为质数,k为自然数,且 p^kpk 小于等于当前剩余石子数), ...
- 洛谷P4018 Roy&October之取石子
题目背景 \(Roy\)和\(October\)两人在玩一个取石子的游戏. 题目描述 游戏规则是这样的:共有\(n\)个石子,两人每次都只能取\(p^k\)个(\(p\)为质数,\(k\)为自然数,且 ...
- {HDU}{2516}{取石子游戏}{斐波那契博弈}
题意:给定一堆石子,每个人最多取前一个人取石子数的2被,最少取一个,最后取石子的为赢家,求赢家. 思路:斐波那契博弈,这个题的证明过程太精彩了! 一个重要的定理:任何正整数都可以表示为若干个不连续的斐 ...
随机推荐
- 【HDOJ】2217 Visit
挺好的一道DP. /* 2217 */ #include <iostream> #include <cstdio> #include <cstring> #incl ...
- 部署lvs-rrd监控LVS
1.安装rrdtool .tar.gz cd rrdtool- ./configure -prefix=/usr/local/rrdtool make make instal 安装完毕后将rrdtoo ...
- HDOJ(HDU) 2504 又见GCD(利用最大公约数反推)
Problem Description 有三个正整数a,b,c(0 import java.util.Scanner; public class Main{ public static void ma ...
- HDU4099 Revenge of Fibonacci(高精度+Trie)
Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 204800/204800 K (Java/ ...
- Clairewd’s message - HDU 4300(next[]运用)
题目大意:给两个串第一个串是翻译表(密文可以通过翻译表翻译成明文),第二个串是由密文+明文组成,前面是密文(完整的),后面是明文(未必完整),问能不能把第二个串补全,输出最短的一种可能. 分析:题 ...
- zznu 1068: 进制转换
进制应该属于程序员的看家本事了,也是大家水平告别菜鸟的一个转折,所以进制转换题目是很有意义的, 这个题目是最简单的把二进制数化简成十进制,因为输入有可能有31位,所以无法使用int或者long lon ...
- Appium移动自动化测试(四)--one demo(转)
Appium移动自动化测试(四)--one demo 2015-06-15 20:41 by 虫师, 40514 阅读, 34 评论, 收藏, 编辑 继续更新. ------------------- ...
- PHP学习之[第07讲]PHP5.4 文件操作函数 之 图片计数器的实例
1.filetype():输出文件类型: 2.stat():获取文件的基本属性的数组: 3.clearstatcache().is_executable().isDir().idFile().scan ...
- js日期控件demo
最近在钻研前端,写了个日期控件,内涵代码注释,希望能帮助到大家~ 1.html代码 <!DOCTYPE html> <html xmlns="http://www.w3.o ...
- crowd在更改IP后无法登录的问题
org.codehaus.xfire.fault.XFireFault: Client with address "192.168.1.222", and hostname &qu ...