2020牛客寒假算法基础集训营4

A 欧几里得

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

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

代码:

#include
using namespace std;
long  a[1000];
long  b[1000];
int main(){
    int t;
    cin>>t;
    a[0] =0;
    a[1] = 1;
    for(int i=2;i<=1000;i++){
        a[i] = a[i-1]+a[i-2];
    }
    b[0] =1;
    for(int i=1;i<=998;i++){
        b[i] = a[i+1]+a[i+2];
    }
    for(int i=1;i<=t;i++){
        int n;
        cin>>n;
        cout<endl;
    }
    return 0;
}

B.括号序列

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

代码:

#include
#include<string.h>
#include
using namespace std;
typedef long long ll;
int main(){
    string s;
    cin>>s;
    ll len = s.length();
    stack<char> a;
    if(!a.empty()) a.pop();
    for(int i=0;i){
        if(s[i]=='('||s[i]=='['||s[i]=='{')  a.push(s[i]);
        else if(s[i]==')'&&!a.empty()&&a.top()=='(') a.pop();
        else if(s[i]=='}'&&!a.empty()&&a.top()=='{') a.pop();
        else if(s[i]==']'&&!a.empty()&&a.top()=='[') a.pop();
        else{
            cout<<"No"<<endl;
            return 0;
        }
    }
    if(a.empty()) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    return 0;
}

 

C子段乘积

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

 

代码:

#include
using namespace std;
const int mod = 998244353;
const int maxn = 2e5+10;
typedef long long ll;
ll a[maxn];
ll ans;
ll Power(ll x,ll y){
    ll res =1;
    while(y){
        if(y&1) res=res*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return res;
}
int main(){
    ll n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)   
        scanf("%lld",&a[i]);
    ll temp = 1;
    for(int l=1,r=1;r<=n;r++){
        if(!a[r]){
            temp=1,l=r+1;
            continue;
        }
        temp =temp*a[r]%mod;
        while(r-l+1>k){
            temp =temp*Power(a[l],mod-2)%mod;
            l++;
        }
        if(r-l+1==k) ans = max(ans,temp);
    }
    cout<endl;
    return 0;
}

 

D子段异或

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

思路:

例子:

a      0          2        1              3             2          1

        0     0^2=2    2^1=3   3^3=0    0^2=2   2^1=3

  0: 2次   2:2次  3:2次

子段异或为0:[1,1] ,     [2,4]     ,     [1,4]      ,      [3,5]     ,     [4,6]

       0          2 1 3        0 2 1 3            1 3 2             3 2 1       

答案是:5 = 1+0+0+2+1+1

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

a^b=a 则b=0  异或数值为第一个a的区间[l1,r1],异或数值为第二个a的区间[l1,r2],则异或数值为b的区间为[r1+1,r2]

就[3,5]这个区间来说,[1,2]这个区间的异或的值为2,[3,5]区间的异或值为0,2^(1^3^2)=2, 2这个数值出现的次数为2次,ans+=(2-1);

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

 

因此题目询问异或值为0的区间有多少个,区间[l,r]中1<=l<=r<=n,l可以等于r,所以初始化mp[0]=1,本身就算一个。

代码

#include
#include
#include
using namespace std; 
typedef long long ll;
const int maxn = 2e5+10;
ll a[maxn];
mapmp;
int main(){
    int n;
    cin>>n;
    ll ans= 0;
    mp[0]=1;
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        a[i]^=a[i-1];
        ans+=mp[a[i]];
        mp[a[i]]++;
    }
    cout<endl;
    return 0;
}

 

E.最小表达式

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

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

代码:

#include
#include<string.h>
#include
using namespace std;
typedef long long ll;
const int maxn =5e5+10;
ll a[maxn];
char s[maxn];
int main(){
    scanf("%s",s);
    ll len = strlen(s);
    sort(s,s+len);//char类型也可以排序,加号排在数字的前面
    ll sum=0;
    for(ll i=0;i){
        if(s[i]=='+')
            sum++;
    }    
    ll n = len-1;
    ll cnt = sum+1;//被分为cnt个数
    ll k=0;
    ll y;
    ll m=0;
    while(n>=sum){//保证不遍历到加号
        ll x = 0;
        for(int i=1;i<=cnt;i++){
            x+=(s[n--]-'0');
            if(n<sum)
                break;
        }
        x+=y;
        a[m++] = x%10;
        y = x/10;
    }
    if(y!=0)//跳出循环的时候y的值需要判断
        cout<<y;
    for(ll i=m-1;i>=0;i--)
        cout<<a[i];
    cout<<endl;
    return 0;
}

 

F 树上博弈

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

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

思路:

用样例一来说:如图:节点数为偶数为sum[1],节点数为奇数为sum[0].

只要牛牛和牛妹所在节点之间的距离为偶数,即牛牛会赢。

所以答案就是节点数为偶数的sum[1]*(sum[1]-1)+节点数为奇数的sum[0]*(sum[0]-1)。

代码:

#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
vector<int> road[maxn];
ll sum[3];
void bfs(int now,int dis){
    for(int i=0;i){
        sum[dis%2]++;
        bfs(road[now][i],dis+1);
    }
    return ;
}
int main(){
    ll n;
    cin>>n;
    sum[0] = 1;//根节点为1,初始化sum[0]=1;
    for(int i=2;i<=n;i++){
        int t;
        scanf("%d",&t);
        road[t].push_back(i);
    }
    bfs(1,1);
    ll ans = sum[0]*(sum[0]-1)+sum[1]*(sum[1]-1);
    cout<endl;
    return 0;
}

 

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