A题,签到A Math Problem

给你一个数n,问有多少个k,满足k^k<=n

用快速幂求出k从1到15的幂次,然后每次查询的时候遍历就行了

#include <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#define INF 1e9
using namespace std;
unsigned long long power_mod(long long a, long long b)
{
    long long ans = 1;
    while (b)
    {
        if (b & 1) ans = ans * a;
        a = a * a;
        b >>= 1;
    }
    return ans;
}
int main()
{
    int m=0;
    long long n;
    unsigned long long num[100];
    for(int i=1;i<=16;i++) num[i]=power_mod(i,i);
    while(~scanf("%lld",&n)){
    m=0;
    for(int i=1;i<=15;i++){
        if(n>=num[i]) m++;
        else break;
    }
    printf("%d\n",m);
    }
    return 0;
}

 

E题,CS Course第一眼看上去比较简单,但是思路挺难想的

首先给一串序列,然后给一些查询,每次查询的内容是除去序列中被查询序号的数,之后的与,或,和异或

思路:首先异或是很简单的,因为异或是有逆运算的,就是他自己(即a^b=c < = > a=b^c),但是与和或没有,一开始以为与和或互为逆运算,然后推了一下,wa了,后面想到了用前缀和后缀数组,就可以避开这个数,去求与和或

#include <cstdio>
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <stack>
#define INF 1e9
using namespace std;
    int sw[100005];
    long long a[100005],b[100005],c=0;
    long long a1[100005],b1[100005];
int main()
{
    int n,m;
    int t;
    while(~scanf("%d %d",&n,&m)){
        scanf("%d",&sw[1]);
        a[1]=sw[1];
        b[1]=sw[1];
        c=a[1];
        for(int i=2;i<=n;i++){
            scanf("%d",&sw[i]);
            a[i]=a[i-1]&sw[i];
            b[i]=b[i-1]|sw[i];
            c^=sw[i];
        }
        a1[n]=sw[n];
        b1[n]=sw[n];
        for(int i=n-1;i>=1;i--){
            a1[i]=a1[i+1]&sw[i];
            b1[i]=b1[i+1]|sw[i];
        }
        for(int i=0;i<m;i++){
            scanf("%d",&t);
            if(t==1) printf("%lld %lld %lld\n",a1[2],b1[2],c^sw[t]);
            else if(t==n) printf("%lld %lld %lld\n",a[n-1],b[n-1],c^sw[t]);
            else {
                long long q,w;
                q=a[t-1]&a1[t+1];
                w=b[t-1]|b1[t+1];
                printf("%lld %lld %lld\n",q,w,c^sw[t]);
            }
        }
    }
    return 0;
}

 

然后是G题,对子和顺子。

首先给了两个定义,两个相同的数可以构成对子,而三个连续的数构成顺子

给一串序列,问顺子和对子最多有多少个

思路,就按顺序先把对子确定,然后把顺子确定

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
using namespace std;
int a[1000001];
int main()
{
    int n,i,x;
    while(~scanf("%d",&n))
    {
        memset(a,0,sizeof(a));
        for(i=1;i<=n;i++)
        {
           scanf("%d",&x);
            a[x]++;
        }
        int ans=0;
        for(i=1;i<=n;i++)
        {
            ans+=a[i]/2;
            a[i]=a[i]%2;
            if(a[i]&&a[i+1]%2&&a[i+2])
            {
                ans++;
                a[i]--;
                a[i+1]--;
                a[i+2]--;
            }
        }
  printf("%d\n",ans);
    }
    return 0;
}