9.7模拟赛

 他

【问题描述】

一张长度为n的纸带,我们可以从左至右编号为0-n(纸带最左端标号为
0)。现在有m次操作,每次将纸带沿着某个位置进行折叠,问所有操作之后纸带
的长度是多少。

【输入格式】

第一行两个数字你,m如题意所述。
接下来一行m个整数代表每次折叠的位置。

【输出格式】

一行一个整数代表答案。

【样例输入】

5 2
3 5

【样例输出】

2

【样例解释】

树上有只鸟。

【数据规模与约定】

对于60%的数据,n,m≤3000。 
对于100%的数据,n≤10^18 ,m≤3000。

题解:

代码:

20分骗分 输出最长的段。

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
long long n,ans,a[3020];
int m;
int main(){
    freopen("he.in","r",stdin);
    freopen("he.out","w",stdout);
    scanf("%lld%d",&n,&m);
    for(int i=1;i<=m;i++)scanf("%lld",&a[i]);
    sort(a+1,a+m+1);
    for(int i=1;i<=m;i++)
    ans=max(ans,a[i]-a[i-1]);
    printf("%lld",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

60分并查集

100分模拟 

#include<iostream>
#include<cstdio>
using namespace std;
long long n,l,r,p[30020];                  
int m;
int main(){
    freopen("he.in","r",stdin);
    freopen("he.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=m;i++)cin>>p[i];
    l=0;r=n;
    for(int i=1;i<=m;i++){
        if(p[i]*2>=(r+l))r=p[i];
        else l=p[i];
        for(int j=i+1;j<=m;j++){
            if(p[j]>r)p[j]=2*r-p[j];
            if(p[j]<l)p[j]=2*l-p[j];
        }
    }
    cout<<r-l<<endl;
    fclose(stdin);
    fclose(stdout);
    return 0;
}

开始对于坐标的变换想麻烦了

【问题描述】

给你M,S,L,R求满足L≤ (S×x) mod M≤R最小的正整数x。

【输入格式】

第一行一个数T代表数据组数。
接下来T行每行四个数代表该组数据的M,S,L,R。

【输出格式】

对于每组数据,输出一行代表答案。如果不存在解,输出“−1” 。

【样例输入】

1
5 4 2 3

【样例输出】

2

【样例解释】

叫南小鸟。

【数据规模与约定】

对于30%的数据,保证有解且答案不超过10^6 。 
另外20%的数据,L==R。 
对于100%的数据,1≤T≤100,0≤M,S,L,R≤ 10^9 。

题解 我也bengbier

代码

//copy from other's
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+10; 
int a[N],top;
int erfen(int x){
    int l=1,r=top,mid,res=0;
    while(l<=r){
        mid=(l+r)>>1;
        if(a[mid]>=x) res=mid,r=mid-1;
        else l=mid+1;
    }
    return res;
}
int main(){
    freopen("she.in","r",stdin);
    freopen("she.out","w",stdout);
    int i,j,k,n,m,s,l,r,x,now,t,ans,ans2;
    bool fl;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d",&m,&s,&l,&r);
        if(l>=m){printf("-1
");continue;}
        if(r>=m)r=m-1;
        now=0;fl=0;
        top=0;
        for(n=1;n*n<=m;n++){
            now=(now+s)%m;
            if(l<=now&&now<=r){
                printf("%d
",n);
                fl=1;break;
            }
            a[++top]=now;
        }
        --n;
        int ste=a[top];
        if(fl) continue;
        sort(a+1,a+top+1);
        for(now=1;now*n<=m;now++){
            l=(l-ste+m)%m;r=(r-ste+m)%m;
            if(l>r) {
                if(a[top]>=l){fl=1;break;}
                if(a[1]<=r){fl=1;break;}
            }
            else{
                if(a[top]<l) continue;
                int x=erfen(l);
                if(a[x]<=r){fl=1;break;}
            }
        }
        if(!fl){printf("-1
");continue;}
        ans=now*n;
        now=0;
        for(i=1;i<=top;i++){
            now=(now+s)%m;
            if(l<=now&&now<=r)break;
        }
        ans+=i;
        printf("%d
",ans);
    }
    return 0;
}

【问题描述】

n个人坐成一圈,其中第n个人拿着一个球。每次每个人会以一定的概率向
左边的人和右边的人传球。当所有人都拿到过球之后,最后一个拿到球的人即为
胜者。求第n个人获胜的概率。 (所有人按照编号逆时针坐成一圈)
  • 1
  • 2
  • 3
  • 4

【输入格式】

第一行一个数T代表数据组数。
对于每组数据,第一行两个整数n,k如题意所述。
接下来每行一个实数p代表该人将球传给右边的人的概率。
  • 1
  • 2
  • 3
  • 4

【输出格式】

对于每组数据,一行一个实数代表答案,保留9位小数。
  • 1
  • 2

【样例输入】

1
5 1
0.10
0.20
0.30
0.40
0.50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

【样例输出】

0.007692308
  • 1
  • 2

【样例解释】

然后鸟是我的。
  • 1
  • 2

【数据规模与约定】

对于20%的数据,n≤3。 
对于70%的数据,T,n≤10。 
对于100%的数据,T≤10000,1≤n≤100。

题解 等比数列

代码

#include<cstdio>
#define LDB long double
#define DB double
using namespace std;
const int N=1000+10;
int T,n,k,pre[N],next[N];
LDB p[N],q[N];
void deal(int b){
    int a=pre[b],c=next[b];
    LDB pa=p[a],pb=p[b],pc=p[c];
    p[a]=pa*pb/(1-pa*(1-pb));
    q[a]=1-p[a];
    q[c]=(1-pc)*(1-pb)/(1-pb*(1-pc));
    p[c]=1-q[c];
    next[a]=c;pre[c]=a;
}
LDB solve(){
    if(n<=2) return 1;
    if(n<=3) return k==1?p[1]:q[2];
    for(int i=1;i<=n;i++) pre[i]=i-1,next[i]=i+1;
    pre[1]=n;next[n]=1;
    if(k==1){
        for(int i=2;i<n-1;i++) deal(i);
        return p[1];
    }
    if(k==n-1){
        for(int i=2;i<n-1;i++) deal(i);
        return q[n-1];
    }
    for(int i=2;i<n-1;i++) if(i!=k) deal(i);
    deal(k);
    return q[k]*p[1]+p[k]*q[n-1];
}
DB v;
#define name "it"
int main(){
    freopen(name".in","r",stdin);
    freopen(name".out","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%lf",&v);
            p[i]=v;
            q[i]=1-v;
        }
        printf("%.9lf
",(DB)solve());
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
原文地址:https://www.cnblogs.com/zzyh/p/7488756.html