[结论]JZOJ 5912 VanUSee

Description

        众所周知,cqf童鞋对哲学有着深入的理解和认识,并常常将哲学思想应用在实际生活中,例如锻炼摔角技术或者研究化(fa)学。
       由于cqf童鞋哲学造诣太过高深,以至于影响到了pty,他们常常给在一块VanUSee。Van的都是一些像“装备回收交易自由”、“开局一条鲲进化全靠吞”、“今晚八点是兄弟就来肝”这样高端大气上档次的著名USee。
       有一天他们决定Van一个亲民的USee来和大家分享他们的哲学心路历程
规则是这样的:
       “给定两个串S和T,|S| >= |T|。
       cqf和pty轮流操作串S,cqf先手。
       对于每次操作,cqf或pty会选择删掉S的第一位或最后一位。
       当操作以后的串的长度等于|T|时,游戏停止。
       如果停止时的串=T,则pty获胜,否则cqf获胜。”
       cqf和pty的哲学思维都很强,他们都能采取最优的策略来行动
       作为高级玩家的苏巴先生在一旁观战,他早已看穿了这个USee的本质,当两个串给出的那一瞬间胜负已分,然而不是所有围观者的水平都像苏巴先生那么高,其中也没有五年级的积分小哥,他们又想知道结果,于是围观者们找到了能预见一局围棋接下来40手的你。
 

Input

有多组数据
第一行一个正整数t表示数据组数
接下来t组数据,每组数据两行,接下来总共2t行
   第一行一个字符串S
    第二行一个字符串T
字符串仅由小写字符组成

Output

t行,对于每一组数据输出双方都是最优策略时谁是赢家(“cqf”或者“pty”,不含引号,小写)
 

Sample Input

5
aba
b
bab
b
aaab
ab
xyz
mnk
xyz
xyz

 

Sample Output

pty
pty
cqf
cqf
pty
样例解释:
对于第一组S=“aba”,T=“b”
cqf无论删掉头还是尾,pty都可以删掉另一个来使剩下的是“b”
对于第三组S=“aaab”,T=“ab”
cqf只需第一次删掉“b”,以后就永远不能达到“ab”了
 

Data Constraint

对于30%的数据,1<=|T|<=|S|<=20
对于100%的数据,1<=t<=10  1<=|T|<=|S|<=100000
 

Hint

这题确实很有趣。

分析

首先我们知道,最优策略就是和对方进行相反操作(显而易见)

然后我们先讨论串一减掉串二剩下字符个数为偶数的情况

首先如果有个字符串在正中间pty必赢

然后我们考虑字符串各往左右偏移一格的情况

pty可以在对方删掉一边以后再删一次那一边,然后对方为了赢会反转操作,那么就可以向左/右多进一格,也只能多进一个

那么偶数情况只有两种:

1、正中间

2、中间左右各偏移一格都是串二

考虑奇数,容易想到和偶数也差不多一个情况(2)

 

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
string a,b;
int main() {
    freopen("vanusee.in","r",stdin);
    freopen("vanusee.out","w",stdout);
    int t;
    scanf("%d",&t);
    while (t--) {
        cin>>a>>b;
        int l1=a.length(),l2=b.length();
        if (l1<=l2) {
            if (a==b) {
                printf("pty\n");
                continue;
            }
            printf("cqf\n");
            continue;
        }
        if (!((l1-l2)%2)) {
            string aleft=a.substr((l1-l2>>1)-1,l2),
            amid=a.substr((l1-l2>>1),l2),
            aright=a.substr((l1-l2>>1)+1,l2);
            if (aleft==aright&&aleft==b||amid==b) {
                printf("pty\n");
                continue;
            }
            printf("cqf\n");
            continue;
        }
        string aleft=a.substr(l1-l2>>1,l2),
        aright=a.substr((l1-l2>>1)+1,l2);
        if (aleft==aright&&aleft==b)
            printf("pty\n");
            else printf("cqf\n");
    }
}
View Code

 

posted @ 2018-10-19 20:21  Vagari  阅读(233)  评论(0编辑  收藏  举报