HDU 5229 博弈思维

题意:总共有N 个串, 从中拿出2个串来,两人轮流进行两种操作

操作1:   将两个串中随机拿出一个非空串,删掉其末尾字母

操作2:   如果两个串相同且非空才能执行该操作,清空两个串;

谁面临无法执行操作时 ,  判为输,  两人足够机灵

题解:明显  如果两个串相同则必定先生赢,两个人为了避免对手拿到必胜状态一定会尽量使两个串差距大。策略为拿两个串中最小的串,既能使对家面临两个串都为空的状态或者是两个串不相等的非必胜状态。两人同时采取最优策略,  那么很明显最终的输赢只和取的A和B 串长有关,   A的长度加上B的长度为奇数,先手胜, 否则后手赢。 还有一种情况就是初始状态A串和B串相等,  那么先手胜。所以只需要跑一遍循环记录之前出现的奇数串和偶数串数目和与之相同串的数目
,  便可以求出胜率

太久没动脑子了 ,   题目想不出来, 看了官方题解才明白该如何做,  加油吧

代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<map>
using namespace std;
map<string, int> mymap;
int gcd(int a, int b)
{
    if(b == 0)  return a;
    return gcd(b, a%b);
}
int main()
{
     int T, n;
     char s1[210005];
     scanf("%d", &T);

     while(T--)
     {
       scanf("%d", &n);
       int sum = 0, ou , ji;
       ou = ji = 0, sum = 0;
       mymap.clear();
       for(int i = 1; i <= n; i++)
       {
          scanf("%s", s1);
          if(mymap[s1]) sum += mymap[s1];
          mymap[s1] ++;
          int len = strlen(s1);
          if(len & 1)  sum += ou, ji++;
          else sum += ji, ou++;
       }
       int kk = (n*(n-1))/2;
       int k = gcd(sum, kk);
       printf("%d/%d\n", sum/k, kk/k);
     }
}
时间: 2024-11-17 07:43:30

HDU 5229 博弈思维的相关文章

hdu 5229 ZCC loves strings

题意: CC有N个字符串,他正在和Miss G.用这N个字符串玩一个小游戏.ZCC会从这N个串中等概率随机选两个字符串(不可以是同一个).然后,ZCC和Miss G.轮流操作.Miss G.总是先操作的.在每轮中,操作者可以选择操作A或操作B. 操作A:在两个串中选择一个当前非空的串,然后在这个串的末尾删去一个字符. 操作B: 若当前两个串完全相同且非空,则可以使用这个操作.此时两个串都被清空. 不能操作的玩家输掉了这个游戏. ZCC想要知道他输掉游戏的概率是多少(也就是Miss G.获胜的概率

HDU 1525 博弈

Euclid's Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1880    Accepted Submission(s): 825 Problem Description Two players, Stan and Ollie, play, starting with two natural numbers. Stan,

hdu 3537(博弈,翻硬币)

题意:给定了每个正面朝上的硬币的位置,然后每次可以翻1,2,3枚硬币,并且最右边的硬币开始必须是正面朝上的. 分析: 约束条件6:每次可以翻动一个.二个或三个硬币.(Mock Turtles游戏) 初始编号从0开始. 当N==1时,硬币为:正,先手必胜,所以sg[0]=1. 当N==2时,硬币为:反正,先手必赢,先手操作后可能为:反反或正反,方案数为2,所以sg[1]=2. 当N==3时,硬币为:反反正,先手必赢,先手操作后可能为:反反反.反正反.正反正.正正反,方案数为4,所以sg[2]=4.

hdu 1848 博弈之SG函数的使用

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1848 题目简单描述为: 1.  这是一个二人游戏;2.  一共有3堆石子,数量分别是m, n, p个:3.  两人轮流走;4.  每走一步可以选择任意一堆石子,然后取走f个:5.  f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8-等数量):6.  最先取光所有石子的人为胜者:假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢. 代码为: ? 1 2 3 4 5 6 7 8 9

HDU 1525 (博弈) Euclid&#39;s Game

感觉这道题用PN大法好像不顶用了,可耻地看了题解. 考虑一下简单的必胜状态,某一个数是另一个数的倍数的时候是必胜状态. 从这个角度考虑一下:游戏进行了奇数步还是偶数步决定了哪一方赢. 如果b > 2a,那么这一方就有权利改变游戏步数的奇偶性,从而到达对自己有利的状态,所以这是一个必胜状态. 如果a < b < 2a,那么下一步只能到达(b-a, a)状态,一直模拟就行. 1 #include <cstdio> 2 #include <algorithm> 3 us

HDU 2147 (博弈) kiki&#39;s game

无奈英语不好又被坑,看到棋子能左移下移左下移,想当然地以为是Wythoff博弈了,=u= 题的意思是说每次只能选一个方向移动一步,所以找找规律就是横纵坐标为奇数的时候是必败状态. 从http://www.cnblogs.com/chaosheng/archive/2012/05/29/2524725.html 盗过来一张图比较好说明: 1 #include <cstdio> 2 3 int main() 4 { 5 int n, m; 6 while(scanf("%d%d"

Hakase and Nano HDU - 6266 (博弈+思维)

http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[1000005]; 5 6 int main() 7 { 8 int t, i, n, d, x; 9 scanf("%d", &t); 10 while(t--) 11 { 12 x = 0; 13 scanf(&quo

HDU 5996 博弈

http://acm.hdu.edu.cn/showproblem.php?pid=5996 博弈论待补. 这题变化了一下,因为注意到奇数层的东西(层数从1开始),对手可以模仿地动,那就相当于没动. 比如从第5层,我选择去了第4,他去第3,我去2,他去1,结果还是到我.所以只需要把偶数层的东西,拿出来, 就是n个石头的博弈了. 异或起来,判断是否等于0,就可以了.博弈论好差,寒假补. #include <cstdio> #include <cstdlib> #include <

hdu 4550 贪心 思维题 不错

http://acm.hdu.edu.cn/showproblem.php?pid=4550 想了挺久,然后各种分类 终于AC,如果是现场,对自己没信心的话,估计还是要WA,,,,,,然后搜题解,发现人家都认为是简单题,看来我还是太弱了,牡丹江没有做出来K看来还是自己贪心和思维有问题 d是一个Deque 最朴素的算法是,如果当前的数<=d.front(),那么插入队列的前面,否则插入队列后面,但是有零所以需要单独处理,还是自己多举例找规律 我的策略: 1.记录0的个数zero,最小非零的数的个数