Educational Codeforces Round 57 (Rated for Div. 2) ABCDEF题解
题目总链接:https://codeforces.com/contest/1096
A. Find Divisible
题意:
给出l,r,在[l,r]里面找两个数x,y,使得y%x==0,保证有解。
题解:
直接输出l,2*l就好啦,但我还是写了个循环...
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ;
int T;
ll l,r;
int main(){
cin>>T;
while(T--){
scanf("%I64d%I64d",&l,&r);
for(ll i=l;i<=r;i++){
if(i*<=r){
printf("%I64d %I64d\n",i,*i);
break ;
}
} }
return ;
}
B. Substring Removal
题意:
给出一个字符串,现在要你删掉一个子串,使得剩下的串有不多于一个的字符。
题解:
从两端找连续的相同字符串并且统计个数,然后算算就可以了。
注意一下所有字符串都相等的情况。
还有一种情况就是两段连续的字符串字符都相等,那么这时就可以删掉中间的,这个个数也比较好统计。
具体见代码(注意中间计算过程不要爆int):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+,MOD = ;
int n;
char s[N];
int main(){
scanf("%d",&n);
scanf("%s",s);
char fir = s[];
int i;
ll cnt1=,cnt2=;
for(i=;i<n;i++){
if(s[i]==fir) cnt1++;
else break ;
}
char last = s[n-];
for(i=n-;i>=;i--){
if(s[i]==last) cnt2++;
else break ;
}
ll ans = (cnt1+cnt2+)%MOD;
if(last==fir){
ans=(ans+cnt1*cnt2)%MOD;
}
cout<<ans<<endl;
return ;
}
C. Polygon for the Angle
题意:
给出一个角度(0<=angle<180),求出最小的正多边形,满足其中存在一个内接三角形的内角与给出的角度相等。
题解:
我的做法比较暴力了,先说说我的吧:
n边形的内角和为(n-2)*180,然后可以知道其每个内角为(n-2)*180/n,利用外接圆+一些圆的性质(圆心角等于二倍圆周角)可以知道一个正n边形的内接三角形的最小角为180/n。
之后只要判断angle%(180/n)是否为0就是了。注意最小角可以为小数,所以我直接是暴力循环...
正解是这样的,首先推出最小角为180/n,然后如果满足angle%(180/n)==0的话,则有n*angle=t*180。
由于180和angle为已知量,我们就可以求出g=gcd(angle,180),然后等式则有n*angle/g = t*180/g。
由这可以知道n=x*180/g , t=y*angle/g,我们知道,这里的t满足t*180/n=angle,当t=n-2时,这时就是正多边形的内角,所以有限制条件:1<=t<=n-2。
我们取x=y=1,这里的n就是答案了(贪心),但是可能会存在这种情况:t=n-1,这时不符合限制条件的,这里我们只要取x=2就行了。
可以证明,当x>=2时,t<=n-2恒成立。
给出我的暴力代码....
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
int ang;
int main(){
cin>>T;
while(T--){
scanf("%d",&ang);
double ans ;
int flag;
for(int i=;i<=;i++){
ans = (double)/i;
flag=;
if(%i!=) for(int j=;;j++){
if(j*ans>ang){
flag=;
break ;
}else if((double)j*ans==(double)ang){
cout<<i<<endl;
flag=;
break ;
}
}
if(flag==) continue ;
else if(flag==) break ;
if(ang%(int)ans==&&ans*(i-)>=ang){
cout<<i<<endl;
break ;
}
}
}
return ;
}
D. Easy Problem
题意:
给出一个字符串,现在要求删去一些字符,使得字符串中不含"hard"子序列,删去一个字符有相应代价,问最小代价。
题解:
如果不存在"hard"子序列的话,我们只需要将其中一个字符删完就行。
我们考虑用动态规划来做,dp(i,j)表示长度为i的字符串中,将第j个删完的最小代价。因为对于每一个字符都有删与不删两种选择。
那么转移方程就为:if(s[j]=='r')(举例)dp(i,j)=min(dp(i,j-1),dp(i-1,j)+a[j]) ; else dp(i,j)=dp(i-1,j).
意思第一个方程的意思即为要么将"r"字符删完,要么将之前的"h"或者"a"的字符删完,求两者的最小代价。
最后求min(dp(n,0),dp(n,1),dp(n,2),dp(n,3))即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+;
ll dp[N][];
//dp(i,j):前i个位置,将第j个删完的最小代价。
char s[N];
ll a[N];
int n;
int main(){
scanf("%d",&n);
scanf("%s",s+);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++){
dp[i][]=dp[i-][]+(s[i]=='h')*a[i];
dp[i][]=min(dp[i-][],dp[i-][]+(s[i]=='a')*a[i]);
dp[i][]=min(dp[i-][],dp[i-][]+(s[i]=='r')*a[i]);
dp[i][]=min(dp[i-][],dp[i-][]+(s[i]=='d')*a[i]);
}
cout<<min({dp[n][],dp[n][],dp[n][],dp[n][]});
return ;
}
E. The Top Scorer
题意:
给出p,s,r,p即人头数,s即每个人得分的总和,r即主人公的分数下限。
现在每个人都忘了自己的分数是多少,只有主人公知道自己的分数下限,问最后主人公获胜的概率是多少。
ps:当有多个人分数相同时,获胜概率为其除以相应人数。
题解:
这题全场A的人数最少,但也的确有点难度。
通过每个人去划分s,可以联想到“插板法”的计算方法。
我们可以看看一个类似的问题:x1+x2+x3+x4+x5=20,0<=xi<=5,问解的情况有多少种。
这实际上是有上界的问题,如果存在的话应该用容斥原理去解。
我们也可以将这个题限定一个上界,设g(s,p,m):p个人,分数和为s,每个人分数不超过m的情况数,这就类似于刚才说的问题。
主要问题是g的计算,我们首先算出总情况:C(s-1+p,p-1)。在这些情况中会有些不符合要求的情况,那么我们减去至少有一个人分数大于m的情况:C(p,1)*C(s-1+p-1*(m+1),p-1)。
这里会多减去一些情况(可以将每个人看做一个独立的集合),然后再加回来....
最后可以得出g的计算方法为:
然后观察一下数据范围,发现可以枚举,那么我们就枚举主人公的得分,再枚举有多少个人分数与之相同,最后计算一下就OK。
本体细节有点多,写的时候注意下,提示:组合。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ,MOD = ;
ll p,s,r;
ll fac[N+N];
ll qp(ll a,ll b){
ll ans = ;
while(b){
if(b&) ans=ans*a%MOD;
a=a*a%MOD;
b>>=;
}
return ans ;
}
ll inv(ll x){
return qp(x,MOD-);
}
ll C(ll n,ll m){
if(n==m) return ;
if(m>n) return ;
return fac[n]*inv(fac[m]*fac[n-m]%MOD)%MOD;
}
ll g(ll S,ll P,ll m){
ll ans=,tmp;
if(!S && !P) return ; //!!
for(int i=;i<=P;i++){
tmp = C(P,i)*C(S+P--i*(m+),P-)%MOD;
if(i&) ans-=tmp;
else ans+=tmp;
ans%=MOD;
if(ans<) ans+=MOD;
}
return ans ;
}
int main(){
cin>>p>>s>>r;
fac[]=;
for(int i=;i<=1e4;i++) fac[i]=fac[i-]*i%MOD;
ll w=;
for(int t=r;t<=s;t++){
for(int q=;q<=p;q++){
if(s-q*t<) continue ;
w=(w+(C(p-,q-)*g(s-q*t,p-q,t-)%MOD)*inv(q)%MOD)%MOD;
}
}
cout<<w*inv(C(s--r+p,p-))%MOD;
return ;
}
F. Inversion Expectation
题意:
给你一个1-n的排列,但现在缺失了一些数字,现在要求逆序对个数的期望值。
题解:
注意这里是期望,期望是线性的,可以分开来算。
这个题主要考虑四种情况:(假设-1的个数为cnt)
1.未知与未知。这种情况的期望值为(cnt-1)*cnt/4,因为对于一个排列,都会存在另一个与之相反的排列,他们的总逆序对个数为(cnt-1)*cnt/2。我们就可以看作每个排列的逆序对个数为(cnt-1)*cnt/4。
2.左边未知与右边已知;
3.左边已知与右边未知。
上面两种情况思考的方式都是一样的,拿第二种情况来说吧,我们只需要统计未出现的数字中有多少个比当前这个已知数大(假设为num),以及当前已知数左边有多少个位置为-1(假设为len)。
那么对于每个位置,产生一个逆序对的概率为num/cnt,其期望也为num/cnt,那么对于当前这个已知数,它对答案的贡献为len*num/cnt。
另外一种情况同样的求法。
4.已知与已知。这时的期望值就是逆序对的个数,用树状数组或者归并排序求一下就好了。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+,MOD = ;
int n;
int a[N],c[N],large[N],vis[N];
int lowbit(int x){
return x&(-x);
}
ll qp(ll A,ll B){
ll ans=;
while(B){
if(B&) ans=ans*A%MOD;
A=A*A%MOD;
B>>=;
}
return ans ;
}
ll inv(ll x){
return qp(x,MOD-);
}
void update(int p,int x){
for(;p<=n;p+=lowbit(p)) c[p]+=x;
}
ll getsum(int p){
ll cnt = ;
for(;p>;p-=lowbit(p)) cnt+=c[p];
return cnt ;
}
int main(){
scanf("%d",&n);
ll cnt = ,ans =,num;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==-) cnt++;
else vis[a[i]]=;
}
int cur = ;
for(int i=n;i>=;i--){
large[i]=cur;
cur+=!vis[i];
}
//Case1:
ans=(ans+(cnt-)*cnt%MOD*inv()%MOD)%MOD;
//Case2:
num = ;
for(int i=;i<=n;i++){
if(a[i]==-) num++;
else{
ll len = large[a[i]];
ans=(ans+num*len%MOD*inv(cnt)%MOD)%MOD;
}
}
//Case3:
num = ;
for(int i=n;i>=;i--){
if(a[i]==-) num++;
else{
ll len = cnt-large[a[i]];
ans=(ans+num*len%MOD*inv(cnt)%MOD)%MOD;
}
}
//Case4:
for(int i=n;i>=;i--){
if(a[i]==-) continue ;
ans=(ans+getsum(a[i]))%MOD;
update(a[i],);
}
cout<<ans;
return ;
}
最近事情好多啊~马上又要期末考了,也要稍微准备下了,再不复习就滑铁卢了啊啊啊。
Educational Codeforces Round 57 (Rated for Div. 2) ABCDEF题解的更多相关文章
- Educational Codeforces Round 48 (Rated for Div. 2) CD题解
		Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ... 
- Educational Codeforces Round 59 (Rated for Div. 2) DE题解
		Educational Codeforces Round 59 (Rated for Div. 2) D. Compression 题目链接:https://codeforces.com/contes ... 
- Educational Codeforces Round 57 (Rated for Div. 2) D dp
		https://codeforces.com/contest/1096/problem/D 题意 给一个串s,删掉一个字符的代价为a[i],问使得s的子串不含"hard"的最小代价 ... 
- Educational Codeforces Round 57 (Rated for Div. 2) C 正多边形 + 枚举
		https://codeforces.com/contest/1096/problem/C 题意 问是否存在一正多边形内三点构成的角度数为ang,若存在输出最小边数 题解 三点构成的角是个圆周角,假设 ... 
- Educational Codeforces Round 57 (Rated for Div. 2)
		我好菜啊. A - Find Divisible 好像没什么可说的. #include<cstdio> #include<cstring> #include<algori ... 
- Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
		#include<bits/stdc++.h>using namespace std;char s[100007];long long a[100007];long long dp[100 ... 
- Educational Codeforces Round 57 (Rated for Div. 2) 前三个题补题
		感慨 最终就做出来一个题,第二题差一点公式想错了,又是一波掉分,不过我相信我一定能爬上去的 A Find Divisible(思维) 上来就T了,后来直接想到了题解的O(1)解法,直接输出左边界和左边 ... 
- Educational Codeforces Round 41 (Rated for Div. 2) ABCDEF
		最近打的比较少...就只有这么点题解了. A. Tetris time limit per test 1 second memory limit per test 256 megabytes inpu ... 
- Educational Codeforces Round 80 (Rated for Div. 2)部分题解
		A. Deadline 题目链接 题目大意 给你\(n,d\)两个数,问是否存在\(x\)使得\(x+\frac{d}{x+1}\leq n\),其中\(\frac{d}{x+1}\)向上取整. 解题 ... 
随机推荐
- Eloquent: 修改器
			感觉好长时间没写东西了,一方面主要是自己的角色发生了变化,每天要面对各种各样的事情和突发事件,不能再有一个完整的长时间让自己静下来写代码,或者写文章. 另一方面现在公司技术栈不再停留在只有 Larav ... 
- centos7 php7 安装php扩展
			yum install php70w.x86_64 php70w-cli.x86_64 php70w-common.x86_64 php70w-gd.x86_64 php70w-ldap.x86_64 ... 
- HDU 5293 Tree chain problem 树形DP
			题意: 给出一棵\(n\)个节点的树和\(m\)条链,每条链有一个权值. 从中选出若干条链,两两不相交,并且使得权值之和最大. 分析: 题解 #include <cstdio> #incl ... 
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架2
			本篇目的:封装一些抽象类 1::封装日志相关类 2:封装一个Service操作类 3:封装缓存操作类 4:封装其他一些常用Helper 1.1在Framework项目里面建立好相关操作类文件夹,以便于 ... 
- echarts 地图的背景色和各省颜色配置以及地图饼图联动
			myChart.on(ecConfig.EVENT.MAP_SELECTED, function (param) { var selected = param.selected; var str = ... 
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目4
			2014-04-23 18:17 题目:设计一个停车位的类. 解法:停车位,就要有停车.取车的功能了.另外我还加了一个工作线程用于计费,每秒给那些有车的车位加1块钱费用. 代码: // 8.4 Des ... 
- 《Cracking the Coding Interview》——第5章:位操作——题目3
			2014-03-19 05:57 题目:给定一个整数N,求出比N大,而且二进制表示中和N有相同个数的‘1’的最小的数,比如3是‘11’,接下来的5是‘101’,再接下来的6是‘110’. 解法:从低位 ... 
- 如何创造财富?硅谷创业之父 Paul Graham 《黑客与画家》思维导图
			先送上亚马逊传送门:<黑客与画家>:硅谷创业之父 Paul Graham 文集 再送上一个思维导图: 下载大图:http://caifujianghu.com/article/ruhe-c ... 
- Java 遍历Map集合的方法
			方法一:通过Map.keySet,遍历key和value Map<String, Object> map = new HashMap<>(); for (String key ... 
- jmeter运行脚本后,请求偶发性的传参错误
			问题现象:jmeter写好脚本后,请求偶发性的传参错误 排查过程:1.结合报错返回值,看是不是线程并发引起: 2.排除线程并发引起后,看看是不是取值策略:如果是参数化,看看是不是每次迭代,每次都取唯一 ... 
