牛客OI周賽14-普及組全部題解

eg:好久不見的普及組題目,自信滿滿以爲自己ak了,結果C題莫名被卡常(後來開了氧氣優化就過了,我一直以爲氧氣優化評測機會自己開不用手動開),D題公式精度問題被卡,最後rk14,btw牛客一場上綠還是很高興的嘿嘿嘿。在這裏插入圖片描述
傳送門

A

題意:統計一個字符串裏有多少個不同的字符。
題解:map或者set隨便搞。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+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;
}
char s[maxn];
map<char,int>mp; 
int main(){
	scanf("%s",&s);
	int len=strlen(s);
	for(int i=0;i<len;i++)mp[s[i]] ++;
	printf("%d\n",mp.size());
	return 0;
}

B

題意:類似於統計水仙花數,一組1e6範圍。
題解:讀入一個判斷一個即可。

#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 n,ans;
ll quick(ll a,int b){
	ll res=1;
	while(b){
		if(b&1)res=res*a;
		a=a*a;
		b>>=1;
	}
	return res;
}
bool check(ll x){
	ll res=0,t=0,xx=x;
	while(xx){
		t++;
		xx/=10;
	}
	xx=x;
	while(x){
		ll k=x%10;
		res+=quick(k,t);
		x/=10;
	}
	if(res==xx)return true;
	return false;
}
int main(){
	scanf("%d",&n); 
	for(int i=1;i<=n;i++){
		ll x;
		scanf("%lld",&x);
		if(check(x))ans++;
	}
	printf("%d\n",ans);
	return 0;
}

C

題意:給出一顆無根樹,讓你確定他的根,使得深度之和最小。
題解:沒看懂官方題解,我的做法是找到樹的重心,然後跑一遍dfs即可。複雜度應該是O(2n),可能vector被卡常了?,以後還是記得開氧氣優化。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+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 n,ans,size=INF;
vector<int>G[maxn];
int son[maxn],vis[maxn];
void dfs(int cur){
	vis[cur]=1;
	son[cur]=0;
	int tmp=0;
	for(int i=0;i<G[cur].size();i++){
		int u=G[cur][i];
		if(!vis[u]){
			dfs(u);
			son[cur]+=son[u]+1;
			tmp=max(tmp,son[u]+1); 
		}
	}
	tmp=max(tmp,n-son[cur]-1);
	if(tmp<size || tmp==size && cur<ans){
		ans=cur;
		size=tmp;
	}
}
ll sum=0;
void dfs2(int x,int fa,int dep){
	for(int i=0;i<G[x].size();i++){
		int u=G[x][i];
		if(u==fa)continue;
		dfs2(u,x,dep+1);
	}
	sum=sum+1ll*dep;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1); 
	dfs2(ans,-1,0);
	printf("%lld\n",sum);
	return 0;
}

D

題意:對於每個點i有pi的概率往右走,問走完n個點的期望是多少。
題解:概率dp的題目。設did_i爲在當前第i個任務到結束還有多久,那麼對於第i個點它有pip_i的概率跳到後面一天還有1pi1-p_i的概率回到前面一天,所以對應的方程就爲(1pi)di1+dipidi+1=1-(1-p_i)d_{i-1}+d_i-p_id_{i+1}=1,那麼列出所有的方程組,高斯消元即可解決,btw如果直接用高斯消元會有精度問題最後只能85,但如果我們直接拿On掃一遍的話就可以過了。。

#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 n;
double a[maxn],f[maxn][5],d[maxn];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%lf",&a[i]);
	for(int i=1;i<=n;i++)
		d[i+1]=(d[i]-1+(a[i]-1)*d[i-1])/a[i];
	printf("%.3lf\n",-d[n+1]);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章