首页 > Codeforces Round #370 (Div. 2)

Codeforces Round #370 (Div. 2)

A - Memory and Crow

这题我没看题意,看了样例猜了一下就AC了,题目好像还挺复杂的。

#include
using namespace std;
int a[100005];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++) scanf("%d",&a[i]);for(int i=1;i"%d ",a[i]+a[i+1]);printf("%d
",a[n]);return 0;
}
View Code

 

 B - Memory and Trident

题目大意:一个人可以往上下左右走,给你一串操作,问你最少改变几个能回到原地。

 

思路:将上下分成一堆,左右分成一堆,改变的时候优先同一堆里面的互换。这样能

保证次数最少。代码写的有点搓。

#include
using namespace std;
const int N=1e5+5;
char s[N];
int vis[4];
int main()
{scanf("%s",s);int len=strlen(s);if(len%2){puts("-1");return 0;}for(int i=0;i){if(s[i]=='U') vis[0]++;else if(s[i]=='D') vis[1]++;else if(s[i]=='L') vis[2]++;else vis[3]++;}if((vis[0]+vis[1])%2==0){int a=(vis[0]+vis[1])/2-min(vis[0],vis[1]);int b=(vis[2]+vis[3])/2-min(vis[2],vis[3]);cout<endl;}else{int a=(vis[0]+vis[1]-1)/2-min(vis[0],vis[1]);//cout<int b=(vis[2]+vis[3]-1)/2-min(vis[2],vis[3]);cout<1<<endl;}return 0;
}
View Code

 

C - Memory and De-Evolution

题目大意:给你两个边长分别为x和y的等边三角形,问你最少通过多少次改变可以把x变成y(x>y)

每次改变可以改变一条边,且改变后三边依旧能构成三角形。

 

思路:想了一会就想出来了,反过来模拟,从y模拟到x,每次y都取出最小的边把它变成能变成

的最大值,等到最小的边都大于x了就结束。

#include
using namespace std;
int x,y;
int a[3];
int main()
{cin>>x>>y;a[0]=a[1]=a[2]=y;int i=0;int ans=0;for(;;i++){ans++;a[i%3]=a[(i+1)%3]+a[(i+2)%3]-1;//printf("%d %d %d
",a[0],a[1],a[2]);if(min(a[(i+1)%3],a[(i+2)%3])>=x) break;}cout<endl;return 0;
}
View Code

 

D - Memory and Scores

题目大意:两个人有初试分数a和b,有 t  轮游戏,每轮游戏每人随机得到[-k,k]中的一个数加

到自己的分数中,问你k轮以后,有多少个结果是 第一个人得分数大于第二个人的。结果对1e9+7取模。

 

思路:用dp[i][j] 表示进行到 i 轮,分数为得到的分数为j 的方案数。

状态转移方程,dp[i][j]=dp[i-1] [j-k]+dp[i-1][j-k+1]+...+dp[i-1][j+k]。

直接这样写可能会超时,我们考虑用前缀和优化,即每一轮更新

的时候保存当前轮dp的前缀和,用于更新下一轮。最后就是计算

方案总数的问题了。

#include
#define ll long long
using namespace std;
const int N=2*1e5+1;
ll dp[101][N],a[N],b[N];
ll x,y,k,t;
const ll mod=1e9+7;
int main()
{cin>>x>>y>>k>>t;ll up=k*t*2;dp[0][k*t]=1;for(ll i=0;i<=up;i++){if(i==0) a[i]=dp[0][i];else a[i]=a[i-1]+dp[0][i];}ll *p=a,*q=b,*g;for(ll i=1;i<=t;i++){for(ll j=0;j<=up;j++){ll l=j-k,r=j+k;l=max((ll)0,l);r=min(up,r);ll t=dp[i][j];if(l==0) dp[i][j]=(dp[i][j]+p[r])%mod;else dp[i][j]=(dp[i][j]+p[r]-p[l-1]+mod)%mod;if(j==0) q[j]=dp[i][j]%mod;else q[j]=(dp[i][j]+q[j-1])%mod;}g=q;q=p;p=g;}ll ans=0;ll dis=y-x+1;for(ll i=0;i<=up;i++){ll now=i-dis;if(now>up) now=up;if(now>=0) ans=(ans+((dp[t][i])*p[now])%mod)%mod;}cout<endl;return 0;
}
View Code

 

E - Memory and Casinos

题目大意:有n个赌场,每个赌场你赢的概率为p,如果赢了你往右边的赌场走,输了往左边的赌场走,

给你一个范围 l 到 r 问你从 l 开始,最后在 r 赢且不在 l 输的概率是多少,写的时候真的不知道怎么写。。

还是太菜了。

 

思路:我们可以用线段树进行区间合并,我们记L( l , r )为从 l 开始最后在r赢不在且在 l 永远不输的概率,

R( l , r )为从 r 开始,最后在 r 赢,且永远不在 l 输的概率。我们对线段树的每个节点保存当前区间的这

两个值,每个节点保存该区间的 L 和 R 值。那么两个区间该如何合并呢?

我们可以先考虑只有两个点的情况 a 点和 b 点,求从 a 开始,最终在 b 点赢,且在 a 点永远不输的概率,

且 在 a 点赢的概率为p1,b 点为 p2,那么我们可以知道我们要求的概率就是一下式子的和

p1*p2         a(win)   b(win)

p1 * ( ( 1 - p2 ) * p1 ) * p2        a(win) b(lose) a(win) b(win)

p1 * ( ( 1 - p2 ) * p1)^2 * p2     a(w) ( b(l)  a(w)  b(l)  a(w) ) b(w)

.............

p1 * ( ( 1 - p2 ) * p1)^n * p2

求和就是等比数列求和。

那么对于两个区间也是同理,对于两个区间a,b,他们的L,R分别为  L1 , L2 , R1  R2,合并之后的 L 为 L3  R 为 R3

那么 L3 为以下式子的和

L1 * L2

L1 * ( ( 1 - L2 ) * R1 ) * L2

L1 * ( ( 1 - L2 ) * R1 )^2  * L2

............

L1 * ( ( 1 - L2 ) * R1 ) ^n * L2

 

R3 为以下式子的和

R2

( 1 - R2 ) * R1 * L2

( 1 - R2 ) * R1 *( ( 1 - L2 ) * R1 ) * L2

( 1 - R2 ) * R1 *( ( 1 - L2 ) * R1 )^2 * L2

.............

( 1 - R2 ) * R1 *( ( 1 - L2 ) * R1 )^n * L2

这样就能完成线段树的区间合并了。

#include
#define pdd pair
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int N=1e5+5;
pdd st[N<<2];
int n,q;
pdd Merge(pdd x,pdd y)
{pdd ans;ans.fi=(x.fi*y.fi)/(1.0-x.se*(1.0-y.fi));ans.se=y.se+((1.0-y.se)*x.se*y.fi)/(1.0-(1.0-y.fi)*x.se);return ans;
}
void build(int l,int r,int rt)
{if(l==r){double a,b;scanf("%lf%lf",&a,&b);st[rt].fi=a/b; st[rt].se=a/b;return;}int m=(l+r)>>1;build(lson);build(rson);st[rt]=Merge(st[ls],st[rs]);
}
void updata(int l,int r,int rt,int x,double a,double b)
{if(l==r && r==x){st[rt].fi=a/b;st[rt].se=a/b;return;}int m=(l+r)>>1;if(x<=m) updata(lson,x,a,b);else updata(rson,x,a,b);st[rt]=Merge(st[ls],st[rs]);
}
pdd query(int L,int R,int l,int r,int rt)
{if(l>=L && r<=R) return st[rt];int m=(l+r)>>1;if(R<=m) return query(L,R,lson);else if(L>m) return query(L,R,rson);else return Merge(query(L,R,lson),query(L,R,rson));
}
int main()
{cin>>n>>q;build(1,n,1);while(q--){int op;scanf("%d",&op);if(op==1){int  x;double a,b;scanf("%d%lf%lf",&x,&a,&b);updata(1,n,1,x,a,b);}else{int l,r;scanf("%d%d",&l,&r);pdd ans=query(l,r,1,n,1);printf("%.12f
",ans.fi);}}return 0;
}
View Code

 

转载于:https://www.cnblogs.com/CJLHY/p/7240669.html

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • #include #include #include #include #include #include #include

  • 题目:表示数值的字符串 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。 解题: 数值错误的形式有多种多样,但是正确的...

  • 加法伺候  //超过20位数值相加---------------------------------------- function bigNumAdd(a, b) {if (!(typeof a === "string" && typeof b === "string")) return console.log("传入参数必...

  • 业务场景: 从中文字句中匹配出指定的中文子字符串 .这样的情况我在工作中遇到非常多, 特梳理总结如下. 难点: 处理GBK和utf8之类的字符编码, 同时正则匹配Pattern中包含汉字,要汉字正常发挥作用,必须非常谨慎.推荐最好统一为utf8编码,如果不是这种最优情况,也有酌情处理. 往往一个具有普适性的正则表达式会简化程...

  • 简单record 一下 #include // 'struct sockaddr_in' #include #include // 'struct ifreq' and 'struct if_nameindex' #include #inc...