17-05-24模拟赛

T1:

(1)将两种数分别放入两个队列中,对当前的两个数进行比较,将较小的数放入答案栈并进行扩展即可。

(2)从前往后维护答案栈的单调不增性,若删的数字达到m个则将剩余数字全部进栈,若答案栈搜完但删的数字仍不到m个则从后往前删去数字直到删的数字达到m个。

Code:

 1 #include<iostream> 
 2 #include<cmath> 
 3 #include<cstdio> 
 4 #include<cstdlib> 
 5 #include<cstring> 
 6 #include<algorithm> 
 7 using namespace std; 
 8 int q[2][50005],qu[30005],head[2],tail[2]; 
 9 char ch[200005]; 
10 int k,m,cnt=1,x,del=0; 
11 int main() 
12 { 
13     scanf("%d%d",&k,&m);qu[1]=1;q[0][1]=3;q[1][1]=9; 
14     head[0]=head[1]=1;tail[1]=tail[0]=1; 
15     while (cnt<k){ 
16         if (q[0][head[0]]<q[1][head[1]])qu[++cnt]=q[0][head[0]],head[0]++; 
17         else qu[++cnt]=q[1][head[1]],head[1]++; 
18         q[0][++tail[0]]=(qu[cnt]<<1)+1;q[1][++tail[1]]=(qu[cnt]<<2)+5; 
19     } 
20     for (int i=1;i<=cnt;++i) printf("%d",qu[i]);cout<<endl; 
21     int cur=0;ch[0]='1'; 
22     for (int i=2;i<=cnt;++i){ 
23         char x[7];sprintf(x,"%d",qu[i]); 
24         for (int j=0;j<strlen(x);++j){ 
25             if (del==m) ch[++cur]=x[j]; 
26             else { 
27                 while (x[j]>ch[cur]&&cur>=0&&del<m) --cur,++del;ch[++cur]=x[j]; 
28             } 
29         } 
30     } 
31     if (del<m) cur-=(m-del); 
32     for (int i=0;i<=cur;++i) printf("%c",ch[i]);return 0; 
33 }

T2:

(1)读入时将大于b的数的a值设为1,小于b的数的a值设为-1,b的a值设为0,并找到b的位置。

(2)从b开始分别向左向右求前缀和,并将该和存在的个数+1。

(3)搜索前缀和的个数,答案加上两个相加为0的前缀和的个数的乘积。

注意到C++语言不支持数组下标为负,所以前缀和初始化时以n开始,答案应加上两个相加为2n的前缀和的个数的乘积。

Code:

 1 #include<iostream> 
 2 #include<cmath> 
 3 #include<cstdio> 
 4 #include<cstdlib> 
 5 #include<cstring> 
 6 #include<algorithm> 
 7 using namespace std; 
 8 int a[100005],l[200005],r[200005],x,y,t,n,b,pos=0,ans; 
 9 int main() 
10 {
11     scanf("%d%d",&n,&b);
12     for (int i=1;i<=n;++i){ 
13         scanf("%d",&t);if(t==b) a[i]=0,pos=i; 
14         else a[i]=t>b?1:-1; 
15     }x=y=n;l[n]=r[n]=1; 
16     for (int i=pos-1;i;--i) x+=a[i],l[x]++; 
17     for (int i=pos+1;i<=n;++i) y+=a[i],r[y]++; 
18     for (int i=1;i<=(n<<1);++i) ans+=l[i]*r[(n<<1)-i]; 
19     printf("%d",ans);return 0; 
20 }

 T3:

 考虑该式的数据范围(m<1017),我们考虑对其进行二分求解。

若m为偶数,注意到(n+n2+...+nm) mod p可以看作((n+n2+...+nm/2) mod p+nm/2*((n+n2+...+nm/2) mod p) mod p) mod p,

则只要递归算出(n+n2+...+nm/2)的值并用快速幂算出nm/2的值即可。

若m为奇数,注意到(n+n2+...+nm) mod p可以看作((n+n2+...+nm/2) mod p+nm/2+1*((n+n2+...+nm/2) mod p+1) mod p) mod p,(“/”向下取整)

则只要递归算出(n+n2+...+nm/2)的值并用快速幂算出nm/2+1的值即可。

Code:

 1 #include<iostream> 
 2 #include<cmath> 
 3 #include<cstdio> 
 4 #include<cstdlib> 
 5 #include<cstring> 
 6 #include<algorithm> 
 7 #define ll long long 
 8 using namespace std; 
 9 ll n,m,p; 
10 ll qpow(ll x){ 
11     ll mul=n,ans=1; 
12     while(x){ 
13         if (x&1ll) ans=(ans*mul)%p; 
14         mul=(mul*mul)%p;x>>=1; 
15     } 
16     return ans; 
17 } 
18 ll sum(ll x){ 
19     if (x==1) return n%p;ll t=sum(x>>1); 
20     if (x&1ll) return (t+qpow((x>>1)+1)*(t+1)%p)%p; 
21     else return (t+qpow(x>>1)*t%p)%p; 
22 } 
23 int main() 
24 { 
25     scanf("%lld%lld%lld",&n,&m,&p); 
26     printf("%lld",sum(m));return 0; 
27 }

T4:期望dp,注意细节处理。

Code:

 1 #include<iostream> 
 2 #include<cmath> 
 3 #include<cstdio> 
 4 #include<cstdlib> 
 5 #include<cstring> 
 6 #include<algorithm> 
 7 using namespace std; 
 8 int R,T; 
 9 double f[503][503],H; 
10 int main() 
11 { 
12     scanf("%d%lf%d",&R,&H,&T); 
13     for (int i=1;i<=T;++i) 
14     for (int j=1;j<=R;++j){ 
15         double sum=H*(R-j)*f[i-1][j];
16         for (int k=1;k<=j;++k){ 
17             double dh=floor(f[i-1][j]-f[i-1][k]); 
18             if (dh<0) dh=0;if (dh>H) dh=H; 
19             sum+=f[i-1][j]*dh; 
20             sum+=(H-dh)*f[i-1][k]+(H+1.0+dh)*(H-dh)/2.0; 
21         }f[i][j]=sum/H/double(R);    
22     }printf("%.3lf",f[T][R]);return 0; 
23 }
原文地址:https://www.cnblogs.com/codingutopia/p/test170524.html