101 Hack 44
来源:互联网 发布:锥形皮带轮数据 编辑:程序博客网 时间:2024/06/05 16:09
A. Picking Numbers(水题)
https://www.hackerrank.com/contests/101hack44/challenges/picking-numbers
题目大意:
给你个数组,问至多有几个数,其中两两相差不到1.
题目分析:
反正数组长度才100,
#include <bits/stdc++.h>using namespace std;#define RE(x) freopen(x,"r",stdin)#define WR(x) freopen(x,"w",stdout)#define ms(x,y) memset(x,y,sizeof(x))#define pb push_back#define mp make_pair#define INF 0x3f3f3f3f#define eps 1e-8typedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;typedef vector<ll> vl;const int M = 1e9 + 7;const double PI = acos(-1.0);const int MAXN = 1e5 + 5;const int MAXM = 1e6 + 5;int main() { //RE("in.txt");WR("out.txt"); int n; int a[105]; cin>>n; for (int i = 0; i < n; i++) cin>>a[i]; sort(a,a+n); int ans=0; for(int i=0;i<n;i++) { int temp=1; for(int j=i+1;j<n;j++) { if(a[j]-a[i]<=1) temp++; } ans=max(ans,temp); } cout<<ans<<endl;}
B.Alice and Bob’s Silly Game(素数统计)
https://www.hackerrank.com/contests/101hack44/challenges/alice-and-bobs-silly-game
题目大意:
有一个集合{1,2,…n},A和B两人轮流从中选一个素数,删去集合中所有该素数的倍数,无法操作者输。问谁赢?
题目分析:
其实就是统计小于n的素数有多少个,之前沈阳赛区有道题可以统计出1e11的,那么本题的1e5自然不在话下,直接套用hdu 5901题模板即可。
#include <bits/stdc++.h>using namespace std;#define RE(x) freopen(x,"r",stdin)#define WR(x) freopen(x,"w",stdout)#define ms(x,y) memset(x,y,sizeof(x))#define pb push_back#define mp make_pair#define INF 0x3f3f3f3f#define eps 1e-8typedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;typedef vector<ll> vl;const int M = 1e9 + 7;const double PI = acos(-1.0);const int MAXN = 1e5 + 5;const int MAXM = 1e6 + 6;ll f[340000],g[340000],n;void init(){ ll i,j,m; for(m=1;m*m<=n;++m)f[m]=n/m-1; for(i=1;i<=m;++i)g[i]=i-1; for(i=2;i<=m;++i){ if(g[i]==g[i-1])continue; for(j=1;j<=min(m-1,n/i/i);++j){ if(i*j<m)f[j]-=f[i*j]-g[i-1]; else f[j]-=g[n/i/j]-g[i-1]; } for(j=m;j>=i*i;--j)g[j]-=g[j/i]-g[i-1]; }}int main(){ int t; cin>>t; while(t--){ cin>>n; init(); if(f[1]&1) cout<<"Alice"<<endl; else { cout<<"Bob"<<endl; } } return 0;}
C.Expected Tree Leaves(概率与期望)
https://www.hackerrank.com/contests/101hack44/challenges/expected-tree-leaves
题目大意:
从一个点1开始,每次随机选择一个点,在其后面连一个点,重复n次。
设叶子节点个数的期望为E,求
题目分析:
首先证明
设点i是叶子节点的概率为
那么点i是叶子节点,当且仅当i+1到n号点都不跟i相连,其概率为
代入E,得
然后就没什么了。
#include <bits/stdc++.h>using namespace std;#define RE(x) freopen(x,"r",stdin)#define WR(x) freopen(x,"w",stdout)#define ms(x,y) memset(x,y,sizeof(x))#define pb push_back#define mp make_pair#define INF 0x3f3f3f3f#define eps 1e-8typedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;typedef vector<ll> vl;const int M = 1e9 + 7;const double PI = acos(-1.0);const int MAXN = 1e5 + 5;const int MAXM = 1e6 + 6;int main() { //RE("in.txt");WR("out.txt"); ll f[MAXN]; f[1]=1; for(int i=2;i<=100000;i++) { f[i]=(f[i-1]*i)%M; } ll n; cin>>n; ll x=n*(1e9+8)/2; x=x%M; cout<<x*f[n]%M<<endl;}
D.Palindromic Subsets(线段树+组合数计算)
https://www.hackerrank.com/contests/101hack44/challenges/palindromic-subsets
题目大意:
输入n和q,还有一个n长的、由小写字母构成的字符串s,进行如下操作:
* 1 i j t:对s的[i,j]子串的字母循环右移t个(下标从0开始)
* 2 i j:问s的[i,j]子串中,有多少个子串可以重排成回文串(这里没注意,导致本题一直没做出来,蠢死了),下标不同认为是不同的子串
n,q范围均为1e5.
题目分析:
因为是重排,所以子串aab也算是“回文串”,因为可以重排为aba,这点一直没注意到。
因此,我们只需要考虑字母出现的次数,而不用关心字母出现的先后顺序。
对每个[i,j]区间,统计每个字母出现的数量记为数组cnt[0…25],记even[i]表示第i个字母的偶数个子集的数目,odd[i]表示第i个字母的奇数个数的子集的数目。
例如对字符串aaaabbb,则cnt[0]=4,cnt[1]=3.
even[0]=8(0个a有1个,2个a有C(4,2)=6个,4个a有1个)
odd[0]=8(1个a有C(4,1)=4个,3个a有C(4,3)=4个)
同理even[1]=4,odd[1]=4。
根据组合数公式可知,若cnt[i]不为0,则
接下来讨论答案,首先如果一个数是回文数,那么至多有一个字母出现奇数次.
首先考虑所有字母出现偶数次的情况,那么答案显然就是
如果有字母出现奇数次,只需让其他的字母出现了偶数次,那么答案就是:
要想处理这个东西,很显然需要跑一下even数组的前缀积和后缀积,然后转化成形如:
接下来就简单了,cnt数组因为具有区间递归的性质,只需用线段树维护即可。因为只有26个字母,因此计算
#include <bits/stdc++.h>using namespace std;#define RE(x) freopen(x,"r",stdin)#define WR(x) freopen(x,"w",stdout)#define ms(x,y) memset(x,y,sizeof(x))#define pb push_back#define mp make_pair#define INF 0x3f3f3f3f#define eps 1e-8#define LEFT idx<<1,begin,mid#define RIGHT idx<<1|1,mid+1,endtypedef long long ll;typedef vector<int> vi;typedef pair<int,int> pi;typedef vector<ll> vl;const int M = 1e9 + 7;const double PI = acos(-1.0);const int MAXN = 1e5 + 5;const int MAXM = 1e6 + 6;int n,q;char s[123456];struct node { int lazy; int cnt[30];}segtree[1<<18],id;ll qmod(ll a,ll b,ll c) { ll ans=1; a=a%c; while(b>0) { if(b&1) ans=(ans*a)%c; b=b/2; a=(a*a)%c; } return ans;}node merge(node a,node b) { node c; c.lazy=0; for(int i=0;i<26;i++) { c.cnt[i]=a.cnt[(i+a.lazy)%26]+b.cnt[(i+b.lazy)%26]; } return c;}void apply(int a,int b) { segtree[a].lazy+=b;}void down(int x) { if(segtree[x].lazy) { apply(x*2, segtree[x].lazy); apply(x*2+1, segtree[x].lazy); node c; c.lazy=0; for(int i=0;i<26;i++) c.cnt[i]=segtree[x].cnt[(i+segtree[x].lazy)%26]; segtree[x]=c; }}void build(int idx,int begin,int end) { if(begin==end) segtree[idx].cnt[s[begin-1]-'a']++; else { int mid=(begin+end)/2; build(LEFT); build(RIGHT); segtree[idx]=merge(segtree[idx*2],segtree[idx*2+1]); }}void update(int idx,int begin,int end,int l,int r,int v) { if(r<begin || end<l) return; if(l<=begin && end<=r) apply(idx,v); else { down(idx); int mid=(begin+end)/2; update(LEFT,l,r,v); update(RIGHT,l,r,v); segtree[idx]=merge(segtree[idx*2],segtree[idx*2+1]); }}node query(int idx,int begin,int end,int l,int r) { if(r<begin || end<l) return id; if(l<=begin && end<=r) return segtree[idx]; else { down(idx); int mid=(begin+end)/2; node a=query(LEFT,l,r); node b=query(RIGHT,l,r); return merge(a,b); }}void shift(int i,int j,int t) { update(1,1,n,i+1,j+1,(26-(t%26))%26);}ll solve(int x,int y) { ll pre[27],suf[27],even[27],odd[27]; for(int i=0;i<27;i++) { pre[i]=0;suf[i]=0;even[i]=0;odd[i]=0; } node d=query(1,1,n,x+1,y+1);//得到结果节点 for(int i=0;i<26;i++) { int c=d.cnt[i]; if(c==0) { even[i]=1; odd[i]=0; } else { even[i]=odd[i]=qmod(2,c-1,M);//直接用1<<(c-1)肯定会爆ll } } pre[0]=1;suf[26]=1; for(int i=1;i<=26;i++) pre[i]=(pre[i-1]*even[i-1])%M; for(int i=25;i>=0;i--) suf[i]=(suf[i+1]*even[i])%M; ll ans=suf[0];//不考虑奇数个字母的出现,答案为(even[0]*...*even[25])%M for(int i=0;i<26;i++) { ll temp=(pre[i]*odd[i])%M; temp=(temp*suf[i+1])%M; ans=(ans+temp)%M; } return ans-1;}int main() { RE("in.txt");WR("out.txt"); cin>>n>>q; cin>>s; // cout<<n<<" "<<q<<endl; // cout<<s<<endl; build(1,1,n); while(q--) { int op,x,y,t; cin>>op; if(op==1) { cin>>x>>y>>t; shift(x,y,t); } else { cin>>x>>y; cout<<solve(x,y)<<endl; } } }
- 101 Hack 44
- HACK
- HACK
- hack
- Hack
- hack
- hack
- hack
- hack
- HACK
- hack
- hack
- 读《50 Android Hacks》笔记整理Hack 44~Hack 50
- Hackerrank 101 Hack 42 Array Pairs
- [HackerRank 101 Hack 42]Array Pairs
- [HackerRank 101 Hack 51] Train Trip
- [HackerRank 101 Hack 51] Small Cubes
- [HackerRank 101 Hack 51] Testing the Game
- 详解javascript立即执行函数表达式(IIFE)
- T460/s 安装Sierra 10.12.2 成功分享……
- jquery实现iframe自适应高度
- zynq-7000 HDMI zedboard 构建以及输出显示
- javascript基础:对象的继承、添加对象方法
- 101 Hack 44
- ubuntu 16.04 启用root用户方法
- PHP微信支付 支付结果通用通知获取不到数据的问题
- ecshop价格范围区间用户自定义选择价格代码
- IOS-Rtmp视频播放
- LeetCode笔记:392. Is Subsequence
- 安卓使用Picasso封装图片加载工具类
- Error:Execution failed for task ':app:mergeDebugResources'. > Crunching Cruncher bg_btn.9.png
- 任务