牛客算法週週練全部題解

eg:感覺牛客算法週週練的題目還是挺好的,有一定的思維量,時間也很友好,大家都可以打一打。
傳送門

A 相反數

題意:給出一個數字,將其翻轉並與原數相加,輸出這個數字。
題解:高精度都用不上,簽到題。

//
//  main.cpp
//  acm
//
//  Created by Mac on 2020/3/26.
//  Copyright © 2020 Mac. All rights reserved.
//
 
#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "math.h"
#include "queue"
#include "map"
#include "set"
#include "vector"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int N=3e5+10;
const ll Mod=998244353;
ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int n;
int doit(int x){
    int res=0;
    while(x){
        res=res*10+x%10;
        x/=10;
    }
    return res;
}
int main(){
    scanf("%d",&n);
    printf("%d\n",n+doit(n));
    return 0;
}

C 完全平方數

題意:求區間[L,R]之內的完全平方數個數。
題解:範圍是1e9,我們先預處理所有的完全平方數,然後使用二分查找即可,有一個坑點,就是0也是完全平方數。

//
//  main.cpp
//  acm
//
//  Created by Mac on 2020/3/26.
//  Copyright © 2020 Mac. All rights reserved.
//
  
#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "math.h"
#include "queue"
#include "map"
#include "set"
#include "vector"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int N=3e5+10;
const ll Mod=998244353;
ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int a[maxn],cnt;
int main(){
    for(int i=1;i*i<=mod-7;i++)a[i]=i*i,cnt=i;
    int T;
    scanf("%d",&T);
    while(T--){
        int l,r;
        scanf("%d%d",&l,&r);
        int pos1=lower_bound(a+1,a+1+cnt,l)-a;
        int pos2=lower_bound(a+1,a+1+cnt,r)-a;
        int ans;
        if(r==a[pos2])ans=pos2-pos1+1;
        else ans=pos2-pos1;
        if(l==0)ans++;
        printf("%d\n",ans);
    }
    return 0;
}

D 小H和遊戲

題意:有一棵樹,每次選擇一個結點,其距離爲2以內的點都會被標記一次,每次輸出這個結點已經被標記的次數。
題解:一開始想的是dfs後來發現t飛了,發現並查集可以搞這道題,開一個數組d[N],表示每個點被選擇的次數,同時用一個數組F[N][2],F[I][1]表示I的兒子選擇的次數,F[I][2]表示I的孫子被選擇的次數,之後並查集維護統計答案即可。

//
//  main.cpp
//  acm
//
//  Created by Mac on 2020/3/26.
//  Copyright © 2020 Mac. All rights reserved.
//
 
#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "math.h"
#include "queue"
#include "map"
#include "set"
#include "vector"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int N=7e5+50100;
const ll Mod=998244353;
ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int fa[N],f[N][3],d[N];
int n,m;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        if(!fa[u])fa[u]=v;
        else fa[v]=u;
    }
    while(m--){
        int x;
        scanf("%d",&x);
        d[x]++;
        int num=0;
        if(fa[x]){
            f[fa[x]][1]++;
            f[fa[x]][2]++;
            num=f[fa[x]][1];
            if(fa[fa[x]])f[fa[fa[x]]][2]++;
        }else num=d[x];
        printf("%d\n",d[fa[x]]+d[fa[fa[x]]]+f[x][2]+num);
    }
    return 0;
}

B Music Problem

題意:給出若干個數字,問其中部分和是不是3600的整數倍。
題解:兩個思路。第一個思路是多重揹包,顯然,將所有的數字對3600取模,每個數字ai可以有若干個,問題就轉換成了這麼多數字能否恰好放滿3600的問題。第二個思路是bitset,f[i]=1表示存在一種情況使得可以加到i,那麼每次將整個bitset左移x位再或上去即可。

//
//  main.cpp
//  acm
//
//  Created by Mac on 2020/3/26.
//  Copyright © 2020 Mac. All rights reserved.
//
 
#include "stdio.h"
#include "string.h"
#include "iostream"
#include "algorithm"
#include "math.h"
#include "queue"
#include "map"
#include "set"
#include "vector"
#include "stack"
#include "bitset"
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const int N=7e5+5010;
const ll Mod=998244353;
ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int n;
bitset<7202>f;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        f.reset();f[0]=1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            x%=3600;
            f|=f<<x;
            f|=f>>3600;
        }
        if(f[3600])puts("YES");
        else puts("NO");
    }
    return 0;
}

E 水題(water)

題意:給出一個數列公式,判斷x是否是其中一項,如果是 求出第幾項再進行m進制轉換,如果不是 輸出x%min(13,m)+1皇后的問題的解。
題解:數列公式是斐波那契公式,然後這道題就成了水題,13皇后問題可以預處理一下得到。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
    ll f=1,x=0;char ch;
    do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
    do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
    return f*x;
}
int a[]={-1,1,0,0,2,10,4,40,92,352,724,2680,14200,73712,365596};
ll f[100];
ll x,m;
int main(){
	f[1]=f[2]=1;
	for(int i=3;i<=100;i++)f[i]=f[i-1]+f[i-2];
	scanf("%lld%lld",&x,&m);
	int flag=0;
	for(int i=1;i<=80;i++)if(f[i]==x)flag=1; 
	if(flag){
		ll ans=1e18,num=0,sum=0;
		for(int i=2;i<=100;i++){
			if(m%i)continue;
			num=sum=0;
			while(m%i==0)num++,m/=i;
			ll tmp=x;
			while(tmp)sum+=tmp/i,tmp/=i;
			ans=min(ans,sum/num);
		}
		printf("%lld\n",ans);
	}else printf("%d\n",a[x%min(13ll,m)+1]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章