牛客网OJ题解--20210131

两条斜线

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

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

NC18951-两条斜线

题目链接

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

题目描述

平面上有N个点,用两个斜率分别为1和-1的斜线,尽可能的穿过更多的点,输出这个最大数量值。保证1<=N<=1000,0<=x[i],y[i]<=999。第一行是N,第二行是N个点的横坐标,第三行是N个点的纵坐标。

测试样例

输入

4
1 4 4 5
3 0 2 3

输出

4

说明

(1,3) (4,0) (4,2) (5,3)四个点都可以被经过

解题思路

我们假设两个斜线分别是y=x+r1和y=-x+r2,我们每次都任取两个点分别求出r1,r2,然后统计在这两个斜线上的顶点的总数量,记录最大值。

解题代码

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

//假设y=x+r1,y=-x+r2
int main()
{
    int n;
    int sum = 0;
    cin >> n;
    int x[1000] = {};
    int y[1000] = {};
    int vis[1000] = {};
    for (int i = 0; i < n; i++)
    {
        cin >> x[i];
    }
    for (int i = 0; i < n; i++)
    {
        cin >> y[i];
    }
    int r1, r2;
    int tmp = 0;
    for (int i = 0; i < n; i++)
    {
        r1 = y[i] - x[i];
        //任取一个点计算出斜率为1的r1值
        for (int j = 0; j < n; j++)
        {
            tmp = 0;
            r2 = y[j] + x[j];
            //任取一个点计算出斜率为-1的r2值
            for (int k = 0; k < n; k++)
            {
                if (x[k] + y[k] == r2 || y[k] - x[k] == r1)
                {
                    //统计在这两条上的点
                    tmp++; 
                }
            }
            if (sum < tmp)
            {
                //记录最大值
                sum = tmp; 
            }
        }
    }
    cout << sum << endl;
    system("pause");
    return 0;
}

NC21297-手机号码

题目链接

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

题目描述

第一行给出一个数字n和m,n表示一个电话号码的位数,m表示接下来给出的mg个号码前缀(注意,可能会出现1,12,123这样有重复的前缀)。接下来给出m行是m个号码前缀。

测试样例

样例1

输入

7 3
0 
1
911

输出

7990000

样例2

输入

10 3
0
1
911

输出

7990000000

样例3

输入

8 3
1
12
123

输出

90000000

样例4

输入

9 3
12
13
14

输出

970000000

样例5

输入

3 1
411

输出

999

解题思路

我们知道实际上就是先默认有10^n中情况(每一位都是0~9十个取值)。对于一个前缀为123长度为3,那么以123开头的情况(一共有10^(n-3)个情况)就都排除了,但是同时要完成去重1前缀和12前缀的这种情况即可。

解题代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n, m;
    cin >> n >> m;
    string a[55];
    int vis[55];                //1代表不是另一个前缀的一部分
    long long sum = pow(10, n); //一共有10^n个情况
    for (int i = 1; i <= m; i++)
    {
        cin >> a[i], vis[i] = 1;
    }
    for (int i = 1; i <= m; i++)
    {
        int s = a[i].size(); //前缀的长度
        for (int j = 1; j <= m; j++)
        //检验这个前缀是否是另一个前缀的一部分
        {
            //string的find函数,返还a[j]在a[i]的起始位置,没有则返还为-1
            int d = a[i].find(a[j]);
            if (d == 0 && i != j)
            {
                //是另一个前缀的一部分,比如1是12的前缀的一部分
                vis[i] = 0; //那么他就不是一个前缀了
                break;
            }
        }
        if (vis[i])
        {
            //如果是一个前缀,那么后面的所有情况都是符合前缀开头的,剪掉这种情况
            sum -= (long long)pow(10, n - s);
        }
    }
    cout << sum;
    return 0;
}
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务