牛客网OJ题解--20210306

数圈圈

https://ac.nowcoder.com/acm/problem/14556

本系列记录翀翀😐痛苦的刷题日志,所有题目均来自于牛客网OJ题目,坚持刷题谈起来容易做起来难,希望我可以坚持下去,这里仍然分享一段励志文案:每个人都有梦想,然而有些人把梦想变成了现实,有些人的梦想依旧是梦想,只因为他们为梦想付出的努力程度不一样,他们坚持的时间不一样,最终才有这样的结果。

NC14556-数圈圈

题目链接

https://ac.nowcoder.com/acm/problem/14556

题目描述

tabris有一个习惯,无聊的时候就会数圈圈,无论数字还是字母。 现在tabris更无聊啦,晚上睡不着觉就开始数羊,从a只数到b只。 顺便还数了a到b之间有多少个圈。 但是tabris笨啊,虽然数羊不会数错,但很可能数错圈的个数。但是tabris很难接受自己笨这个事实,所以想问问你他一共应该数出多少个圈,这样tabris才好判断他到底笨不笨啊。

输入一个T,表示数据组数,每组测试数据包含两个正整数a,b。T∈[1,50]a,b∈[1,106]

测试样例

输入

11
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
1 100

输出

0
0
0
1
0
1
0
2
1
1
111

解题思路

水题,主要就是一个取位的问题,可以采用字符也可以模10的方法。但是这道题我用字符会超时,不知道为什么。。。

解题代码

// #include <bits/stdc++.h>
// using namespace std;

// #define ll long long

// ll judge(ll x)
// {
//     ll num = 0;
//     string s = to_string(x);
//     cout << s << endl;
//     for (ll i = 0; i < s.length(); i++)
//     {
//         if (s[i] == '0' || s[i] == '4' || s[i] == '6' || s[i] == '9')
//             num++;
//         if (s[i] == '8')
//             num += 2;
//     }
//     return num;
// }

// int main()
// {
//     ll T;
//     cin >> T;
//     while (T--)
//     {
//         ll a, b;
//         cin >> a >> b;
//         ll ans = 0;
//         for (ll i = a; i <= b; i++)
//         {
//             ans += judge(i);
//         }
//         cout << ans << endl;
//     }
//     system("pause");
//     return 0;
// }

#include <iostream>
using namespace std;
int main()
{
    int t;
    cin >> t;
    for (int i = 0; i < t; i++)
    {
        int a, b;
        cin >> a >> b;
        int sum = 0;
        for (int j = a; j <= b; j++)
        {
            int temp = j;
            while (temp != 0)
            {
                int ans = temp % 10;
                if (ans == 4 || ans == 6 || ans == 9 || ans == 0)
                    sum++;
                else if (ans == 8)
                    sum = sum + 2;
                temp = temp / 10;
            }
        }
        cout << sum << endl;
    }

    system("pause");
    return 0;
}

NC14619-栗酱的异或和

题目链接

https://ac.nowcoder.com/acm/problem/14619

题目描述

栗酱特别喜欢玩石子游戏,就是两个人玩,有n堆石子,每堆有ai个,每次一个人可以轮流选择任意一堆,取走任意多的石子(但不能不取),谁先不能取谁输。栗酱觉得这个游戏很有趣,知道有一天,小太阳告诉她,其实如果两个人足够聪明,游戏的结局一开始就已经注定。栗酱是一个冰雪聪明的女孩子,她不相信,希望你演示给她看。
多组数据,数据第一行T表示数据组数。每组数据第一行一个n,k表示一共有n堆石子,接下来你试图从第k堆开始取,从第二行开始,每隔一个空格一个第i堆石子的数量ai。
n≤105, ai≤109。输出“Yes”或“No”代表从该堆开始取是否可以必胜(如果足够聪明)。

测试样例

输入

2
3 2
1 2 3
2 1
2 1

输出

No
Yes

说明

小太阳哥哥说,如果想赢,就试图把每堆石子数量的异或和变为0,最终便可以获得胜利,不相信自己证一下。小数据较多,不要使用memset,可能导致TLE。

解题思路

nim游戏变式题,可以食用本篇博客《浅谈nim游戏问题》。其实我们可以参考说明一样可以解题。就是如果我们先计算一下除了第k堆以外的石子数量sum,然后我们如果想让对面输,那么就需要给他留下一个石子数量异或和为0的局面,这样他先手就必定输了。但是如果我们没能够一步将这个局面制造给他,那么他就会给我们制造异或0的局面,那么我们在拿石子就必定输了。所以胜负主要关键取决于我们能否先手第一步就制造异或0的局面,所以也就要求我们要拿a个石子,使得a[k]-a^sum=0即a[k]-a和sum数相同,所以a=a[k]-sum,但是a>=0,所以还要保证a[k]>=sum,否则我们就不能一次性给对手制造必输局面。

解题代码

#include <bits/stdc++.h>
using namespace std;

const int N = 2e6 + 10;
int a[N];
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, k;
        cin >> n >> k;
        int sum = 0;
        for (int i = 1; i <= n; i++)
        {
            cin >> a[i];
            if (i == k)
                continue;
            sum ^= a[i];
        }
        if (sum >= a[k])
            cout << "No" << endl;
        else
            cout << "Yes" << endl;
    }
    system("pause");
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务