他
【问题描述】
一张长度为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; }