牛客刷题 - 网易2018校招编程题(思维 & 贪心 & )

版权声明:如果感觉写的不错,转载标明出处链接哦~blog.csdn.net/wyg1997 https://blog.csdn.net/wyg1997/article/details/82971535

这套题的难受还是有的,不过有些题想想还是可以做的,只是有些题用暴力的方法感觉有点失望。


Q1:

在这里插入图片描述

解题思路:这个题很明显,一个只能产奇数,一个只能产偶数,倒着分奇偶跑一遍就行啦~

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        stack<int> s;
        while(n)
        {
            if(n&1)
            {
                n >>= 1;
                s.push(1);
            }
            else
            {
                n = (n-2)>>1;
                s.push(2);
            }
        }
        while(!s.empty())
        {
            printf("%d",s.top());
            s.pop();
        }
        printf("\n");
    }
    return 0;
}

Q2:

在这里插入图片描述

解题思路:这题没说的,直接算就行了。

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
int main()
{
    int n;
    while (~scanf("%d",&n))
    {
        int re = 0;
        int temp = n;
        while (temp)
        {
            re = re*10 + temp%10;
            temp /= 10;
        }
        printf("%d\n",re+n);
    }
    return 0;
}

Q3:

在这里插入图片描述

解题思路:也是过一遍就行了,没难度。

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
int main()
{
    char str[55];
    while (~scanf("%s",str))
    {
        char pre = str[0];
        int length = 1;
        int cnt = 1;
        int l = strlen(str);
        int sum = 0;
        for (int i = 1 ; i < l ; i++)
        {
            if (str[i] != pre)
            {
                pre = str[i];
                cnt++;
                sum += length;
                length = 1;
            }
            else
                length++;
        }
        sum += length;
        printf("%.2lf\n",(double)sum/cnt);
    }
    return 0;
}

Q4:

在这里插入图片描述
解题思路:这个题就有点意思了。用贪心的思想,首先尽量向深处走(使用dfs查看深度),然后就分两种情况:1.把所有步数用光也走不到底,那么答案就是步数。2.如果可以走到最深处,那么剩下的步数就每两步走一个格子(这一句是关键,举几个例子就能想通了)。

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
vector<int> edge[55];
int max_deep;
 
void dfs(int from, int fa, int deep)
{
    max_deep = max(max_deep, deep);
    for (int i = 0 ; i < edge[fa].size() ; i++)
    {
        if (edge[fa][i] == from)
            continue;
        dfs(fa, edge[fa][i], deep+1);
    }
}
int main()
{
    int n, l;
    while(~scanf("%d %d",&n,&l))
    {
        for (int i = 0 ; i < n ; i++)
            edge[i].clear();
        max_deep = 0;
        for (int i = 1 ; i < n ; i++)
        {
            int t;
            scanf("%d",&t);
            edge[i].push_back(t);
            edge[t].push_back(i);
        }
        dfs(0, 0, 0);
        //如果最深的一层走不完,那直接就有结果了
        if (l <= max_deep)
            printf("%d\n",l+1);
        else
            printf("%d\n",max_deep+1+min(n-1-max_deep, (l-max_deep)>>1));
    }
    return 0;
}

Q5:

在这里插入图片描述
解题思路:这个题也有点意思,需要想明白下面几点:1.不是2的倍数的数必须和4的倍数相邻。2.2的倍数的那些数,可以考虑为一个数,例如2 2 2 2其实和一个2是同样的效果,也必须和4相邻(如果不在边界的话)。
所以问题就简单了,统计2的倍数(不是4的倍数),4的倍数,其它奇数的数量,如果4的数量可以满足足够插在上面的数字中,则可以满足。下面代码更直观一些。

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        int n;
        scanf("%d",&n);
        int cnt1 = 0;       //是4的倍数
        int cnt2 = 0;       //不是4的倍数
        int cnt3 = 0;       //这里还要考虑不是2的倍数的数,如果没有,也是Yes
        for (int i = 1 ; i <= n ; i++)
        {
            int t;
            scanf("%d",&t);
            if (t%4 == 0)
                cnt1++;
            else if (t%2 == 0)
                cnt2++;
            else
                cnt3++;
        }
        if (cnt1 >= cnt3+(cnt2!=0)-1 || cnt3 == 0)
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}

Q6:

在这里插入图片描述
好题啊!!!
解题思路:本以为是个什么dp的问题(因为dp不好,一碰见没思路的计数问题就想到dp)。结果后来看了解题思路,发现就是暴力题:枚举每一个位置的括号,尝试放在各个位置,这时候的LCS一定是length-1,因为只有我们枚举的这个字符位置变了,这个也是最大的LCS,因为我们就移动了一个字符。然后我们把枚举成功的字符串放进set里,结果就是set.size()-1

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <iostream>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
int main()
{
    string str;
    while (cin >> str)
    {
        set<string> s;
        s.insert(str);
        //取每个字符
        for (int i = 0 ; i < str.size() ; i++)
        {
            string pre = str.substr(0, i) + str.substr(i+1);
            //枚举每个位置
            for (int pos = 0 ; pos < pre.size() ; pos++)
            {
                string new_string = pre.substr(0,pos) + str[i] + pre.substr(pos);
                //判断是否合法
                int num = 0;
                for (int j = 0 ; j < new_string.size() ; j++)
                {
                    if (new_string[j] == '(')
                        num++;
                    else
                        num--;
                    if (num < 0)
                        break;
                }
                if (num == 0)
                    s.insert(new_string);
            }
        }
        cout << s.size()-1 << endl;
    }
    return 0;
}

Q7:

在这里插入图片描述
还是一个好题
解题思路:考虑dp,我们反向思考。先画个抽象的图,dp[i][j]表示小Q演奏到i,牛博士演奏到j,可以想到dp[i][j] == dp[j][i],我们假设有三个音符:
在这里插入图片描述
可以发现右半边没画,就是因为两边其实是一样的。
每个结点表示当前结点和下面最优的结点(即花费最小)的贡献之和。
再看看状态是怎么转移的:比如我们看dp[1][2]这个结点,下来要演奏的是3号音符。如果让小Q演奏,那么状态就到了dp[3][2]上,代价为dp[3][2]+abs(num[3]-num[1])。其它的结点也就同理了。

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
LL dp[2005][2005];
int v[2005];
int n;
LL dfs(int i,int j)
{
    int ne = max(i, j) + 1;
    //如果没有下一个音符
    if (ne == n+1)
        return 0;
    if (dp[i][j] != -1)
        return dp[i][j];
 
    dp[i][j] = 1e6*2000+5;
    dp[i][j] = min(dp[i][j], dfs(ne, j) + (i ? abs(v[ne] - v[i]) : 0));
    dp[i][j] = min(dp[i][j], dfs(i, ne) + (j ? abs(v[ne] - v[j]) : 0));
    dp[j][i] = dp[i][j];
    return dp[i][j];
}
int main()
{
    scanf("%d",&n);
    for (int i = 1 ; i <= n ; i++)
        scanf("%d",&v[i]);
    CLR(dp, -1);
    printf("%lld\n",dfs(0,0));
    return 0;
}

Q8:

在这里插入图片描述
解题思路:枚举三个点(确定十字),然后统计在这个十字上的点的数量即可。

代码如下:

#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
struct Dot
{
    int x,y;
}dot[55];
 
bool is_line(int i, int j, int k)
{
    int x1 = dot[i].x - dot[j].x;
    int y1 = dot[i].y - dot[j].y;
     
    int x2 = dot[k].x - dot[j].x;
    int y2 = dot[k].y - dot[j].y;
 
    return (x1*y2 - x2*y1) == 0;
}
int main()
{
    int n;
    scanf("%d",&n);
    for (int i = 1 ; i <= n ; i++)
        scanf("%d",&dot[i].x);
    for (int i = 1 ; i <= n ; i++)
        scanf("%d",&dot[i].y);
     
    int ans = min(n, 3);
    for (int i = 1 ; i <= n ; i++)
    {
        for (int j = 1 ; j <= n ; j++)
        {
            if (i == j)
                continue;
            for (int k = 1 ; k <= n ; k++)
            {
                if (j == k || i == k)
                    continue;
                int num = 3;
                for (int p = 1 ; p <= n ; p++)
                {
                    if (p==i || p==j || p==k)
                        continue;
                    if (is_line(i,j,p))
                        num++;
                    else if ((dot[i].x-dot[j].x)*(dot[k].x-dot[p].x) + (dot[i].y-dot[j].y)*(dot[k].y-dot[p].y) == 0)
                        num++;
                }
                ans = max(ans, num);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wyg1997/article/details/82971535
今日推荐