题目总链接: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题解的更多相关文章

  1. Educational Codeforces Round 48 (Rated for Div. 2) CD题解

    Educational Codeforces Round 48 (Rated for Div. 2) C. Vasya And The Mushrooms 题目链接:https://codeforce ...

  2. Educational Codeforces Round 59 (Rated for Div. 2) DE题解

    Educational Codeforces Round 59 (Rated for Div. 2) D. Compression 题目链接:https://codeforces.com/contes ...

  3. Educational Codeforces Round 57 (Rated for Div. 2) D dp

    https://codeforces.com/contest/1096/problem/D 题意 给一个串s,删掉一个字符的代价为a[i],问使得s的子串不含"hard"的最小代价 ...

  4. Educational Codeforces Round 57 (Rated for Div. 2) C 正多边形 + 枚举

    https://codeforces.com/contest/1096/problem/C 题意 问是否存在一正多边形内三点构成的角度数为ang,若存在输出最小边数 题解 三点构成的角是个圆周角,假设 ...

  5. Educational Codeforces Round 57 (Rated for Div. 2)

    我好菜啊. A - Find Divisible 好像没什么可说的. #include<cstdio> #include<cstring> #include<algori ...

  6. 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 ...

  7. Educational Codeforces Round 57 (Rated for Div. 2) 前三个题补题

    感慨 最终就做出来一个题,第二题差一点公式想错了,又是一波掉分,不过我相信我一定能爬上去的 A Find Divisible(思维) 上来就T了,后来直接想到了题解的O(1)解法,直接输出左边界和左边 ...

  8. Educational Codeforces Round 41 (Rated for Div. 2) ABCDEF

    最近打的比较少...就只有这么点题解了. A. Tetris time limit per test 1 second memory limit per test 256 megabytes inpu ...

  9. Educational Codeforces Round 80 (Rated for Div. 2)部分题解

    A. Deadline 题目链接 题目大意 给你\(n,d\)两个数,问是否存在\(x\)使得\(x+\frac{d}{x+1}\leq n\),其中\(\frac{d}{x+1}\)向上取整. 解题 ...

随机推荐

  1. Eloquent: 修改器

    感觉好长时间没写东西了,一方面主要是自己的角色发生了变化,每天要面对各种各样的事情和突发事件,不能再有一个完整的长时间让自己静下来写代码,或者写文章. 另一方面现在公司技术栈不再停留在只有 Larav ...

  2. centos7 php7 安装php扩展

    yum install php70w.x86_64 php70w-cli.x86_64 php70w-common.x86_64 php70w-gd.x86_64 php70w-ldap.x86_64 ...

  3. HDU 5293 Tree chain problem 树形DP

    题意: 给出一棵\(n\)个节点的树和\(m\)条链,每条链有一个权值. 从中选出若干条链,两两不相交,并且使得权值之和最大. 分析: 题解 #include <cstdio> #incl ...

  4. 亲手搭建一个基于Asp.Net WebApi的项目基础框架2

    本篇目的:封装一些抽象类 1::封装日志相关类 2:封装一个Service操作类 3:封装缓存操作类 4:封装其他一些常用Helper 1.1在Framework项目里面建立好相关操作类文件夹,以便于 ...

  5. echarts 地图的背景色和各省颜色配置以及地图饼图联动

    myChart.on(ecConfig.EVENT.MAP_SELECTED, function (param) { var selected = param.selected; var str = ...

  6. 《Cracking the Coding Interview》——第8章:面向对象设计——题目4

    2014-04-23 18:17 题目:设计一个停车位的类. 解法:停车位,就要有停车.取车的功能了.另外我还加了一个工作线程用于计费,每秒给那些有车的车位加1块钱费用. 代码: // 8.4 Des ...

  7. 《Cracking the Coding Interview》——第5章:位操作——题目3

    2014-03-19 05:57 题目:给定一个整数N,求出比N大,而且二进制表示中和N有相同个数的‘1’的最小的数,比如3是‘11’,接下来的5是‘101’,再接下来的6是‘110’. 解法:从低位 ...

  8. 如何创造财富?硅谷创业之父 Paul Graham 《黑客与画家》思维导图

    先送上亚马逊传送门:<黑客与画家>:硅谷创业之父 Paul Graham 文集 再送上一个思维导图: 下载大图:http://caifujianghu.com/article/ruhe-c ...

  9. Java 遍历Map集合的方法

    方法一:通过Map.keySet,遍历key和value Map<String, Object> map = new HashMap<>(); for (String key ...

  10. jmeter运行脚本后,请求偶发性的传参错误

    问题现象:jmeter写好脚本后,请求偶发性的传参错误 排查过程:1.结合报错返回值,看是不是线程并发引起: 2.排除线程并发引起后,看看是不是取值策略:如果是参数化,看看是不是每次迭代,每次都取唯一 ...