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;
}