牛客寒假算法基础集训营1

集训营涵盖知识点:

第一场:模拟、贪心、动态规划、数学、数据结构

 

A 小a的计算器

链接:https://ac.nowcoder.com/acm/contest/317/A
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

小a的数学基础实在太差了,以至于他只会用计算器算数。他的计算器比较特殊,只有+,−,×,/+,−,×,/(即加减乘除)四种运算。
经过一番周折,小a终于算出了他想要的数,但是他却忘记了最初的数是什么。不过幸运的是他记下了整个操作序列,他想请你帮他算出最初的数
 

输入描述:

第一行两个整数n,Xn,X,分别表示操作次数和最终的数
接下来nn行表示操作序列,每行两个数opt,xopt,x
若opt=1opt=1,则表示将当前数加xx
若opt=2opt=2,则表示将当前数减xx
若opt=3opt=3,则表示将当前数乘xx
若opt=4opt=4,则表示将当前数除以xx

输出描述:

一个整数表示最初的数

示例1

输入

复制

4 6
1 3
2 1
3 3
4 2

输出

复制

2

说明

样例1解释
2+3=55−1=44∗3=1212/2=62+3=55−1=44∗3=1212/2=6

示例2

输入

复制

3 292
3 2
4 3
4 3

输出

复制

1314

备注:

n⩽100,0

 

用结构体存储运算标识,将运算反着进行

#include 

using namespace std;
struct node
{
    int a;
    int b;
};
node num[1005];
int main()
{
    int n;
    long long x;
    cin>>n>>x;
    for(int i=1;i<=n;i++)
    {
        cin>>num[i].a>>num[i].b;
    }
    for(int i=n;i>=1;i--)
    {
        if(num[i].a==1)
        {
            x-=num[i].b;
        }
        else if(num[i].a==2)
        {
            x+=num[i].b;
        }
        else if(num[i].a==3)
        {
            x=x/num[i].b;
        }
        else
        {
            x=x*num[i].b;
        }
    }
    cout<
B 小a与"204"

链接:https://ac.nowcoder.com/acm/contest/317/B
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

小a非常喜欢204204这个数字,因为′a′+′k′=204′a′+′k′=204。
现在他有一个长度为nn的序列,其中只含有2,0,42,0,4这三种数字
设aiai为序列中第ii个数,你需要重新排列这个数列,使得∑ni=1(ai−ai−1)2∑i=1n(ai−ai−1)2最大(公式的含义是:每个数与前一个数差的平方的和)
注意:我们默认a0=0a0=0

输入描述:

第一行一个整数nn
接下来一行nn个整数,第ii个数表示aiai

输出描述:

输出一个整数,表示∑ni=1(ai−ai−1)2∑i=1n(ai−ai−1)2的最大值

示例1

输入

复制

2
2 4

输出

复制

20

说明

样例1解释:按(4,2)(4,2)排列是最优的,此时sum=(4−0)2+(2−4)2=20sum=(4−0)2+(2−4)2=20

示例2

输入

复制

3
2 0 4

输出

复制

36

说明

样例2解释:按(4,0,2)(4,0,2)排列是最优的,此时sum=(4−0)2+(0−4)2+(2−0)2=36sum=(4−0)2+(0−4)2+(2−0)2=36

示例3

输入

复制

5 
2 4 0 2 4

输出

复制

52

备注:

1⩽n⩽1051⩽n⩽105,保证aiai为2/0/42/0/4中的数

由于默认a0=0,那么第一个数应该是最大的。

接下来要想得到最大值,第二个应为最小数,第三个为次最大,第四个为次最小以此类推。

则奇数位的数字从大到小,偶数位的数字从小到大,可以求得最大值

#include 
#include
using namespace std;
int a[100005];
int b[100005];
int main()
{
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>a[i];
    sort(a+1,a+1+n);
    int l=1,r=n;
    for(int i=1; i<=n; i++)
    {
        if(i&1)
            b[i]=a[r--];
        else
        {
            b[i]=a[l++];
        }
    }
    long long num=0;
    for(int i=1;i<=n;i++)
    {
        num+=(b[i]-b[i-1])*(b[i]-b[i-1]);
    }
    cout<
C 小a与星际探索

链接:https://ac.nowcoder.com/acm/contest/317/C
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

小a正在玩一款星际探索游戏,小a需要驾驶着飞船从11号星球出发前往nn号星球。其中每个星球有一个能量指数pp。星球ii能到达星球jj当且仅当pi>pjpi>pj。
同时小a的飞船还有一个耐久度tt,初始时为11号点的能量指数,若小a前往星球jj,那么飞船的耐久度会变为t⊕pjt⊕pj(即tt异或pjpj,关于其定义请自行百度)
小a想知道到达nn号星球时耐久度最大为多少

注意:对于每个位置来说,从它出发可以到达的位置仅与两者的pp有关,与下标无关

输入描述:

第一行一个整数nn,表示星球数
接下来一行有nn个整数,第ii个整数表示pipi

输出描述:

一个整数表示到达nn号星球时最大的耐久度
若不能到达nn号星球或到达时的最大耐久度为00则输出−1−1

示例1

输入

复制

3
457 456 23

输出

复制

478

说明

小a有两种方法到达33号星球
第一种:1→2→31→2→3,最终耐久度为457⊕456⊕23=22457⊕456⊕23=22
第二种:1→31→3,最终耐久度为457⊕23=478457⊕23=478

示例2

输入

复制

4
2 4 4 2

输出

复制

-1

示例3

输入

复制

5
234 233 123 2333 23

输出

复制

253

备注:

1⩽n,∀pi⩽3000

用线性基求最大异或和

#include
#include
#include
#define ll long long
using namespace std;
const int maxn = 1e5*5;
int a[maxn], p[maxn];
int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> p[i];
	for (int i = 1; i = 0; j--)
			if (p[i]>>j&1&&p[0]>p[i]&&p[i]>p[n])
				if (!a[j]) {
					a[j] = p[i];
					break;
				}
				else
					p[i] ^= a[j];
	int ans = p[0] ^ p[n - 1];
	for (int i = 14; i >= 0; i--)
		ans = max(ans, ans^a[i]);
	cout << (p[0]>p[n-1]?ans:-1) << endl;
	return 0;
}
D 小a与黄金街道

 

链接:https://ac.nowcoder.com/acm/contest/317/D
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

小a和小b来到了一条布满了黄金的街道上。它们想要带几块黄金回去,然而这里的城管担心他们拿走的太多,于是要求小a和小b通过做一个游戏来决定最后得到的黄金的数量。
游戏规则是这样的:
假设道路长度为nn米(左端点为00,右端点为nn),同时给出一个数kk(下面会提到kk的用法)
设小a初始时的黄金数量为AA,小b初始时的黄金数量为BB
小a从11出发走向n−1n−1,小b从n−1n−1出发走向11,两人的速度均为1m/s1m/s
假设某一时刻(必须为整数)小a的位置为xx,小b的位置为yy,若gcd(n,x)=1gcd(n,x)=1且gcd(n,y)=1gcd(n,y)=1,那么小a的黄金数量AA会变为A∗kx(kg)A∗kx(kg),小b的黄金数量BB会变为B∗ky(kg)B∗ky(kg)
当小a到达n−1n−1时游戏结束
小a想知道在游戏结束时A+BA+B的值
答案对109+7109+7取模

输入描述:

一行四个整数n,k,A,Bn,k,A,B

输出描述:

输出一个整数表示答案

示例1

输入

复制

4 2 1 1

输出

复制

32

说明

 

初始时A=1,B=1A=1,B=1

第一个时刻如图所示,小a在11,小b在33,满足条件,此时A=1∗21=2,B=1∗23=8A=1∗21=2,B=1∗23=8

 

第二个时刻小a在22,小b在22,不满足条件

 

第三个时刻小a在33,小b在11,满足条件,此时A=2∗23=16,B=8∗21=16A=2∗23=16,B=8∗21=16

此时游戏结束A=2∗23=16,B=8∗21=16A=2∗23=16,B=8∗21=16

A+B=32A+B=32

示例2

输入

复制

5 1 1 1

输出

复制

2

备注:

 

保证3⩽n⩽108,A,B,k⩽10133⩽n⩽108,1⩽A,B,k⩽1013

牛客寒假算法基础集训营1_第1张图片

欧拉函数+快速幂

若gcd(n,x)=1,则gcd(n,n-x)=gcd(n,y)=1。

因为x,y∈(1<-->n-1),则(X1+X2+...+Xi)=(Y1+Y2+...+Yi )。

所以A*k^(X1+X2+...+Xi)  +  B*k^(Y1+Y2+...+Yi ) =  (A+B)*k^(M1+M2+Mi)

(M1+M2+....+Mi)=euler*n/2;

#include 
#define ll long long
using namespace std;
const int  mod= 1e9+7;
ll quick(ll m,ll k)//快速幂
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*m%mod;
        m=m*m%mod;
        k>>=1;
    }
    return res;
}
int main()
{
    ll n,k,a,b;
    cin>>n>>k>>a>>b;
     ll euler=n,t=n;
        for(ll p=2;p*p<=n;p++)
        {
            if(n%p==0)//若等于0,则表明p为n的质因子
            {
                euler=euler/p*(p-1);//euler=n*(1-1/Pi)
                while(n%p==0)//将Pi这个因子全部除净
                    n/=p;
            }
        }
    if(n>1)//若n还没有被除完
        euler=euler/n*(n-1);
    ll sum=euler/2*t;
    cout<<(a+b)*quick(k,sum)%mod<

 

你可能感兴趣的:(牛客寒假算法基础集训营1)