前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【题解】Game With Telephone Numbers

【题解】Game With Telephone Numbers

作者头像
灯珑LoGin
发布2022-10-31 11:12:35
2950
发布2022-10-31 11:12:35
举报
文章被收录于专栏:龙进的专栏

A telephone number is a sequence of exactly 1111 digits such that its first digit is 8.

Vasya and Petya are playing a game. Initially they have a string ss of length nn (nn is odd) consisting of digits. Vasya makes the first move, then players alternate turns. In one move the player must choose a character and erase it from the current string. For example, if the current string 1121, after the player’s move it may be 112, 111 or 121. The game ends when the length of string ss becomes 11. If the resulting string is a telephone number, Vasya wins, otherwise Petya wins.

You have to determine if Vasya has a winning strategy (that is, if Vasya can win the game no matter which characters Petya chooses during his moves).Input

The first line contains one integer nn (13≤n<10513≤n<105, nn is odd) — the length of string ss.

The second line contains the string ss (|s|=n|s|=n) consisting only of decimal digits.Output

If Vasya has a strategy that guarantees him victory, print YES.

Otherwise print NO.

代码语言:javascript
复制
13
8380011223344

output

代码语言:javascript
复制
YES

input

代码语言:javascript
复制
15
807345619350641

output

代码语言:javascript
复制
NO

Note

In the first example Vasya needs to erase the second character. Then Petya cannot erase a character from the remaining string 880011223344 so that it does not become a telephone number.

In the second example after Vasya’s turn Petya can erase one character character 8. The resulting string can’t be a telephone number, because there is no digit 8 at all.

这道题在做的时候卡了我很久,一直没有思路,想了想其实就是这样的一个问题:

1、手机号首位为8,数字长度为11位。总的字符串长度位数位奇数。也就是说,每个玩家操作的次数相等,都是(n-11)/2次

2、V在游戏中是先手,那么在游戏之中,一定是P进行最后一次操作,然后就定胜负。

题目问的是,何种情况下,V才有十足的胜算,也就是说,游戏一开始,他就知道自己赢定了。

那么问题就转化成了:经过V在字符串的前面取(n-11)/2次的不为8的字符的操作,以及P在字符串中取前(n-11)/2个字符8之后,在字符串的第1位是不是字符8?

这样子思考的话,就可以比较快速的解出这道题目

以下是网站上题解的代码

代码语言:javascript
复制
#include<bits/stdc++.h>

using namespace std;

int n;
string s;

int main(){
    cin >> n >> s;
    int cnt1 = (n - 11) / 2;
    int cnt2 = cnt1;
    string res = "";
    for(int i = 0; i < n; ++i){
        if(s[i] == '8'){
            if(cnt1 > 0) --cnt1;
            else res += s[i];
        }
        else{
            if(cnt2 > 0) --cnt2;
            else res += s[i];
        }
    }
    
    if(res[0] == '8') cout << "YES\n";
    else cout << "NO\n";
	return 0;
}

我的方法和网站上的不太一样,我的没有那么直观,但是其实思路是一样的。

代码语言:javascript
复制
#include<iostream>
#include<string>
using namespace std;


int main()
{
    int n;
    cin>>n;
    string s;
    cin>>s;
    int js=0;
    int jss=0;
    bool is_ok = false;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='8')
            js++;
        else{
            jss++;
        }
        if(js==(n-11)/2+1)
        {
            if(jss>(n-11)/2)
                cout<<"NO"<<endl;
            else cout<<"YES"<<endl;
            is_ok=true;
            break;
        }
    }
    if(!is_ok) cout<<"NO"<<endl;

}

网站上的方法是真的进行了分别删除字符串的前(n-11)/2个为‘8’和不为‘8’的字符的操作

而我这个是查找第(n-11)/2+1个‘8’,那么假设它前面的所有’8’都已经被删掉了,然后对于这个’8’,它前面还有jss个非8的字符。如果jss<(n-11)/2,那么就意味着,V可以把这个8前面的所有字符都删掉,那么就能确保自己赢得游戏。

比完赛之后思考了一下,的确我这个方法感觉就是绕了一个大弯,其实这道题只要抓住本质是,为了确保在当前输入情况下,V一定能赢得比赛,那么V就要采取不删除8的策略,把8移动到头部。而P要尽量使得V不能赢得比赛,所以他要采取尽可能地删掉头部的8,防止V把8移动到头部。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020年11月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档