hr上面有好多比赛,形式主要分为笔试型(1-2小时,3-5题)和编程马拉松型(3-7天,8题+)。
hourrank就是一个不错的模拟企业笔试,要求1小时内完成3~4道算法题,目前已经举办了十几届。
https://www.hackerrank.com/contests/hourrank-16/challenges/pile-of-candies
有n堆糖,第i堆糖有c[i]个。定义欢乐度为最少的那堆糖的个数。有每次可以选择一堆糖,将其个数加倍。问:
只取决于最少的那堆糖的个数是不是唯一的就可以,如果是,那么只有1种选法,即选择他,如果不是就是n种选法,因为不管选谁,最小值都是最少的那堆。特殊讨论下n=1
#include
using namespace std;
typedef long long ll;
int n;
int c[111];
int main(){
cin>>n;
for(int i=0;icin>>c[i];
}
if(n==1)
cout<0]*2<<' '<<1<else {
sort(c,c+n);
if(c[0]!=c[1]) {
cout<0]*2,c[1])<<' '<<1<else {
cout<0]<<' '<
https://www.hackerrank.com/contests/hourrank-16/challenges/leonardo-and-lucky-numbers
给你n,问是否存在正整数x,y使得7x+4y=n?
扩展欧几里得算法,模板套进去就行了。
不过也有更高明的算法就是讨论n%4的值,也就是相当于讨论是否存在x,使得 7x%4=n%4 也很简单,就不说了
#include
using namespace std;
typedef long long ll;
ll x,y;
ll exgcd(ll a,ll b) {
if(!b) {
x=1;
y=0;
return a;
}
ll r=exgcd(b,a%b);
ll t=x;
x=y;
y=t-a/b*y;
return r;
}
bool check(ll n) {
ll r=exgcd(7,4);
if(n%r)
return false;
x*=n;
x=((x%4)+4)%4;
y=(n-7*x)/4;
return y>=0;
}
int main(){
int q;ll n;
cin>>q;
while(q--) {
cin>>n;
if(check(n))
cout<<"Yes"<else
cout<<"No"<
https://www.hackerrank.com/contests/hourrank-16/challenges/james-tree
有一棵树,每次等概选取一点,然后计算该点到它能到达的所有点的路径之和,再删除该点的所有出边,直到所有的点都被选中。记路径之和的期望值为 Em ,求 (Em∗n!)%1e9+9 .
一开始想的是,观察到每一种取法的分母是n!,所以考虑直接算每一条路径对Em*n!的贡献,发现有点困难。。。。而且官方题解说的含糊不清,
看了官方题解,是只考虑一种取法的。在一次n的全排列过程中,路径a->b至多被选中1次.路径a->b被选中 当且仅当n的全排列过程里面由这条路径的点构成的子列的排序过程中,a或b最先出现。(否则这条路就断了) 那么,a->b这条路径出现的期望值则为 dis(a,b)⋅2k ,其中k为a->b中经过的点数。
这个公式我想了很久,其实也没那么难理解,还是智商太低了……因为其他n-k个点无论怎么选,既不会破坏a->b路径,也不会影响a->b路径的选取,与a->b路径上的选点是相互独立的事件。
所以呢,问题转化为求所有的 dis(a,b) 和k,用n趟dfs就可以解决了。复杂度 O(n2) .还有一个要注意的就是答案很大,而且n在分母上,先预处理打表求一下乘法逆元就可以了,这都是小问题。
#include
using namespace std;
typedef long long ll;
#define pb push_back
#define mp make_pair
#define RE(x) freopen(x,"r",stdin)
#define WR(x) freopen(x,"w",stdout)
const int M = 1e9+9;
int n;
vectorint ,int> > g[5005];
ll dis[5005][5005];
int dep[5005][5005];
ll fac[5005];
ll f[5005];
int egcd(int a, int b, int &x, int &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
int ans = egcd(b, a % b, x, y);
int temp = x;
x = y;
y = temp - a / b * y;
return ans;
}
int cal(int a, int m = M) {
int x, y;
int gcd = egcd(a, m, x, y);
if (1 % gcd != 0)
return -1;
x *= 1 / gcd;
m = abs(m);
int ans = x % m;
if (ans <= 0)
ans += m;
return ans;
}
void pre() {
fac[1]=1;
for(int i=2;i<=5000;i++)
fac[i]=(fac[i-1]*i)%M;
for(int i=1;i<=5000;i++)
f[i]=cal(i);
}
void dfs(int u,int rt,int fa) {
if(fa==0) {
dis[rt][rt]=0;
dep[rt][rt]=1;
}
for(int i=0;iint v=g[u][i].first,w=g[u][i].second;
if(v!=fa) {
dis[rt][v]=(dis[rt][u]+w)%M;
dep[rt][v]=dep[rt][u]+1;
dfs(v,rt,u);
}
}
}
int main(){
RE("in.txt");
WR("out.txt");
pre();
cin>>n;
int u,v,w;
for(int i=1;icin>>u>>v>>w;
g[u].pb(mp(v,w));
g[v].pb(mp(u,w));
}
memset(dis,0,sizeof(dis));
memset(dep,0,sizeof(dep));
for(int i=1;i<=n;i++) {
dfs(i,i,0);
}
ll ans=0;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
ans=(ans+dis[i][j]*2*f[dep[i][j]])%M;
}
}
ans=(ans*fac[n])%M;
cout<