牛客小白月賽10 A,B,C,D題解
阿新 • • 發佈:2018-12-31
A 勘測:
題目:
思路:
找規律,通過找出前幾天的建設道路的次數發現為斐波那契額數列,然後求前n項的和即可。
程式碼如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=10000000007; const int maxn=5*1e6+5; int n; ll a[maxn]; ll sum[maxn]; int main() { scanf("%d",&n); memset(sum,0,sizeof(sum)); a[0]=0;sum[0]=0;a[1]=1;a[2]=2; sum[1]=1;sum[2]=3; for (int i=3;i<=n;i++) { a[i]=(a[i-1]+a[i-2])%mod; sum[i]=(sum[i-1]+a[i])%mod; } printf("%lld\n",sum[n]%mod); return 0; }
B 數學:
題目:
思路:
根據3,5,8,11倍數的特性來進行判定。
如果不知道倍數特性的話可以看看下面這篇部落格:
程式碼如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; string a; int is[4]; int on[4]={3,5,8,11}; int num=0; void Judge() { int sum=0,sumo=0,sume=0,sum8=0; for (int i=0;i<a.length();i++) { sum+=a[i]-'0'; if((i+1)%2) sumo+=a[i]-'0'; else sume+=a[i]-'0'; } if(sum%3==0) is[0]=1,num++; if(a[a.length()-1]=='0'||a[a.length()-1]=='5') is[1]=1,num++; for (int i=a.length()-1,j=0,k=1;i>=0&&j<3;i--,j++,k*=10) sum8=sum8+(a[i]-'0')*k; if(sum8%8==0) is[2]=1,num++; if(abs(sumo-sume)%11==0) is[3]=1,num++; } int main() { cin>>a; memset (is,0,sizeof(is)); Judge(); if(num) { printf("Yes\n"); for (int i=0;i<4;i++) { if(is[i]) { printf("%d ",on[i]); num--; } } printf("\n"); } else { printf("No\n"); } return 0; }
C 約數
題目:
思路:
求出a,b的gcd, 然後對gcd進行分解。
程式碼如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll a,b; vector<ll>ans; ll gcd (ll a,ll b) { return b==0?a:gcd(b,a%b); } int main() { scanf("%lld%lld",&a,&b); ll g=gcd(a,b); for (ll i=1;i<=sqrt(g);i++) { if(g%i==0) { ans.push_back(i); if(i*i!=g) ans.push_back(g/i); } } sort(ans.begin(),ans.end()); for (int i=0;i<ans.size();i++) { printf("%lld%c",ans[i],i==ans.size()-1?'\n':' '); } return 0; }
D 飢餓
題目:
思路:
將安全的道路建圖, 然後套用迪傑斯特拉演算法。
程式碼如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=9223372036854775807;
const int maxn=1e6+5;
int head[maxn];
int n,m,s,t;
ll d[maxn];
struct edge
{
int to;
int next;
ll len;
};
edge e[200005*4];
void addedge (int id,int u,int v,ll len)
{
e[id].to=v;
e[id].len=len;
e[id].next=head[u];
head[u]=id;
}
void djst()
{
int vis[maxn];
memset(vis,0,sizeof(vis));
for (int i=0;i<=n;i++)
{
d[i]=INF;
}
d[s]=0;
while (1)
{
ll Max=INF;
int u=-1;
for (int i=1;i<=n;i++)
{
if(!vis[i]&&Max>d[i])
{
Max=d[i];
u=i;
}
}
if(u==-1)
break;
vis[u]=1;
for (int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
ll len=e[i].len;
if(!vis[i]&&d[u]+len<d[v])
{
d[v]=d[u]+len;
}
}
}
if(d[t]==INF)
printf("My gold!!!\n");
else
printf("%lld\n",d[t]);
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
memset (head,-1,sizeof(head));
for (int i=0,id=0;i<m;i++)
{
int flag,x,y;
ll len;
scanf("%d%d%d%lld",&flag,&x,&y,&len);
if(flag)
{
addedge(id++,x,y,len);
addedge(id++,y,x,len);
}
}
djst();
return 0;
}