济南-1030试题解题报告
By shenben
本解题报告解析均为100分解题思路。
题意:从1− n中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数
最大可能是多少.
解析:
1、 质因数分解
2、 1->n用质因数指数的相加的形式将1*n累乘起来
3、 扫一遍指数为奇数的质因数都-1,偶数的不变
4、 快速幂乘一遍,同时取模
题意:有n个数,随机选择一段区间,如果这段区间的所有数的平均值在[L,R]中则
你比较厉害。求你比较厉害的概率
解析:(暴力枚举 40分)
100分需要推式子,过程略,最后式子:求S[R]-S[L]
(S[x]=前缀和a[i]-x的逆序对个数)
Fz= S[R]-S[L];
Fm=(n+1)*n/2;
Fz=fm-fz;
Ans=fz/fm(需要约分)
题意:n*m的方阵上有?棵葱,你要修一些栅栏把它们围起来。一个栅栏是一段
沿着网格建造的封闭图形(即要围成一圈) 。各个栅栏之间应该不相交、不重叠
且互相不包含。如果你最多修?个栅栏,那么所有栅栏的长度之和最小是多少
解析:
搜索+各种剪枝
详见代码
题意:
一张长度为n的纸带,我们可以从左至右编号为0 −n(纸带最左端标号为
0) 。现在有m次操作,每次将纸带沿着某个位置进行折叠,问所有操作之后纸带
的长度是多少
解析:
模拟
折痕左边大,右边往左边折,同时右边向左边映射.L不变,R=折痕
折痕右边大,左边往右边折,同时左边向右边映射.L=折痕,R不变
(100分不能用并查集维护,应为并查集依靠数组的size太大)
题意:给你 L,R,S,M,求满足L<=(S*x) mod M<=R最小的正整数x
解析:
略
详见代码
题意:n个人坐成一圈,其中第k个人拿着一个球。每次每个人会以一定的概率向左边的人和右边的人传球。当所有人都拿到过球之后,最后一个拿到球的人即为胜者。求第n个人获胜的概率(所有人按照编号逆时针坐成一圈)
解析:
等比数列(还是推式子)
上午
T1代码:
T2代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define name "jian"
#define ll long long
#ifdef unix
#define LL "%lld"
#else
#define LL "%I64d"
#endif
using namespace std;
const int N=1e6+10;
int n,L,R,a[N],b[N];
ll fz,fm,gy,ans,s[N],c[N];
inline const int read(){
register int x=0,f=1;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
void binary_chop(int l,int r){
if(l==r) return ;
int mid=l+r>>1;
binary_chop(l,mid);binary_chop(mid+1,r);
int p=l,q=l,j=mid+1;
while(p<=mid&&j<=r){
if(s[p]>s[j]){
ans+=mid-p+1;
c[q++]=s[j++];
}
else{
c[q++]=s[p++];
}
}
while(p<=mid) c[q++]=s[p++];
while(j<=r) c[q++]=s[j++];
for(int i=l;i<=r;i++) s[i]=c[i];
}
int main(){
freopen(name".in","r",stdin);
freopen(name".out","w",stdout);
n=read();L=read();R=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) b[i]=a[i]-L;
for(int i=1;i<=n+1;i++) s[i]=s[i-1]+b[i-1];
binary_chop(1,n+1);fz+=ans;
memset(s,0,sizeof s);ans=0;
for(int i=1;i<=n;i++) b[i]=a[i]-R;
for(int i=1;i<=n+1;i++) s[i]=s[i-1]+b[i-1];
reverse(s+1,s+n+2);
binary_chop(1,n+1);fz+=ans;
fm=(ll)n*(n+1)/2;
fz=fm-fz;
gy=__gcd(fz,fm);
fz/=gy;fm/=gy;
if(fm==1) printf(LL"\n",fz);
else printf(LL "/" LL,fz,fm);
fclose(stdin);
fclose(stdout);
return 0;
}
/*
40分代码,长个记性
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define name "jian"
#define ll long long
#ifdef unix
#define LL "%lld"
#else
#define LL "%I64d"
#endif
inline const ll read(){
register ll x=0,f=1;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int N=5e5+10;
int n,p,L,R,a[N];
ll sum[N];
ll fz,fm,gy;
int main(){
freopen(name".in","r",stdin);
freopen(name".out","w",stdout);
n=read();L=read();R=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
fm=(ll)(n+1)*n/2;
double tmp;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
tmp=(double)(sum[j]-sum[i-1])/(j-i+1);//必须用double类型(除法有精度要求),否则会炸
//当时脑残了,还去排序,这是一个数列。连四十分都没有拿到。QAQ
if(tmp>=L&&tmp<=R) fz++;//直接判是否在[L,R]中就好了
}
}
gy=__gcd(fz,fm);
fz/=gy;fm/=gy;
if(fm==1) printf(LL"\n",fz);
else printf(LL "/" LL,fz,fm);
fclose(stdin);
fclose(stdout);
return 0;
}
*/
T3代码:
#include<cstdio>
#include<algorithm>
using namespace std;
inline const int read(){
register int x=0,f=1;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int N=1e6+10;
const int M=20;
int m,n,k,xx[M],yy[M];
int cost[N],s[M];
int tot,nowmask,answer,full;
struct rect{
int x1,x2,y1,y2;
int mask,w;
rect(){}
rect(int _x1,int _y1,int _x2,int _y2){
x1=_x1,y1=_y1,x2=_x2,y2=_y2;
mask=0;
for(int i=0;i<n;i++) if(x1<=xx[i]&&xx[i]<=x2&&y1<=yy[i]&&yy[i]<=y2) mask|=(1<<i);
w=((x2-x1+1)+(y2-y1+1))*2;
if(mask==full) answer=w;
}
}a[N];
void dfs(int cnt,int j,int cost){
if(nowmask==full){
//if(clock()>=1950){printf("%d",answer);exit(0);}
answer=min(answer,cost);return ;
}
if(cnt>=k||j>tot||cost>=answer) return ;
for(int i=j;i<=tot;i++){
if(nowmask&a[i].mask) continue;
nowmask^=a[i].mask;
dfs(cnt+1,i+1,cost+a[i].w);
nowmask^=a[i].mask;
}
}
void DFS(int now,int cnt,int res){
if(now==n){
if(res<answer) answer=res;return;
}
if(res+(k-cnt)*4>=answer) return;
for(int i=1;i<=cnt;i++){
int pres=s[i];
s[i]|=(1<<now);
DFS(now+1,cnt,res-cost[pres]+cost[s[i]]);
s[i]^=(1<<now);
}
if(cnt<k){
s[++cnt]=(1<<now);
DFS(now+1,cnt,res+4);
}
}
#define name "dan"
int main(){
freopen(name".in","r",stdin);
freopen(name".out","w",stdout);
m=read();k=read();n=read();
full=(1<<n)-1;
for(int i=0;i<n;i++) xx[i]=read(),yy[i]=read();
if(n<15){
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
for(int k=j;k<n;k++){
for(int l=k;l<n;l++){
a[++tot]=rect(min(min(xx[i],xx[j]),min(xx[k],xx[l])),min(min(yy[i],yy[j]),min(yy[k],yy[l])),
max(max(xx[i],xx[j]),max(xx[k],xx[l])),max(max(yy[i],yy[j]),max(yy[k],yy[l])));
}
}
}
}
nowmask=0;
dfs(0,1,0);
printf("%d",answer);
}
else{
answer=4000;
for(int i=1;i<=full;i++){
int sx=1001,mx=-1,sy=1001,my=-1;
for(int j=0;j<n;j++){
if((i>>j)&1){
if(xx[j]<sx) sx=xx[j];
if(xx[j]>mx) mx=xx[j];
if(yy[j]<sy) sy=yy[j];
if(yy[j]>my) my=yy[j];
}
}
cost[i]=(mx-sx+1)*2+(my-sy+1)*2;
}
DFS(0,0,0);
printf("%d",answer);
}
fclose(stdin);
fclose(stdout);
return 0;
}
下午
T1代码:
T2代码:
//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\n");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",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\n");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\n",ans);
}
return 0;
}
/*30分代码存档
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
#define name "she"
using namespace std;
inline const ll read(){
register ll x=0,f=1;
register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
ll cas,tx,m,s,l,r;
ll sx=1e6+10;
bool falg;
void go(int tt){
tt++;
while(tt--) puts("-1");
exit(0);
}
int main(){
freopen(name".in","r",stdin);
freopen(name".out","w",stdout);
cas=read();
while(cas--){
m=read();s=read();l=read();r=read();
if(m<=l){puts("-1");continue;}
if(clock()>=900) go(cas);
if(l==r) tx=m*10,falg=1;
for(ll i=1;i<=sx;i++){
if(clock()>=900) go(cas);
if(falg){
if(i>tx){
puts("-1");
falg=0;
break;
}
}
ll tmp=s*i%m;
if(tmp>=l&&tmp<=r){
printf("%d\n",(int)i);
break;
}
if(tmp==1&&i>m){
puts("-1");
break;
}
}
}
return 0;
}
*/
T3代码:
P75
竞赛时间: ????年??月??日??:??-??:??

注意事项(请务必仔细阅读)
【 问题描述】
从1 −
N中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数
最大可能是多少。
【输入格式】
第一行一个数字N。
【输出格式】
一行一个整数代表答案对100000007取模之后的答案。
【样例输入】
7
【样例输出】
144
【样例解释】
但是塔外面有东西。
【数据规模与约定】
对于20%的数据, 1 ≤ N ≤ 100。
对于50%的数据, 1 ≤ N ≤ 5000。
对于70%的数据, 1 ≤ N ≤ 105。
对于100%的数据, 1 ≤ N ≤ 5 × 106。
【问题描述】
有N个数,随机选择一段区间,如果这段区间的所有数的平均值在[𝑙, 𝑟]中则你比较厉害。求你比较厉害的概率。
【输入格式】
第一行有三个数N, l, r,含义如上描述。
接下来一行有N个数代表每一个数的值。
【输出格式】
输出一行一个分数a/b代表答案,其中a, b互质。 如果答案为整数则直接输出该
整数即可。
【样例输入 1】
4 2 3
3 1 2 4
【样例输出 1】
7/10
【样例输入 2】
4 1 4
3 1 2 4
【样例输出 2】
1
【样例解释】
塔外面有棵树。
【数据规模与约定】
对于30%的数据, 1 ≤ N ≤ 104。
对于60%的数据, 1 ≤ N ≤ 105。
对于100%的数据, 1 ≤ N ≤ 5 × 105, 0 < l ≤ r ≤ 100。
【问题描述】
m × m的方阵上有n棵葱, 你要修一些栅栏把它们围起来。 一个栅栏是一段
沿着网格建造的封闭图形( 即要围成一圈)。 各个栅栏之间应该不相交、 不重叠
且互相不包含。 如果你最多修k个栅栏, 那么所有栅栏的长度之和最小是多少?
【 输入格式】
第一行三个整数m, k, n。
接下来n行每行两个整数x, y代表某棵葱的位置。
【 输出格式】
一行一个整数代表答案。
【样例输入 1】
6 1 4
1 3
4 2
4 4
6 4
【 样例输出 1】
18
【样例输入 2】
6 2 4
1 3
4 2
4 4
6 4
【 样例输出 2】
16
【 样例解释】
你猜树上有啥。
【数据规模与约定】
对于10%的数据, k = 1。
对于30%的数据, k ≤ 2。
对于60%的数据, n ≤ 10。
对于100%的数据, 1 ≤ k ≤ n ≤ 16, m ≤ 1000。
P76
竞赛时间: ????年??月??日??:??-??:??
题目名称 |
他 |
她 |
它 |
名称 |
he |
she |
it |
输入 |
he.in |
she.in |
it.in |
输出 |
he.out |
she.out |
it.out |
每个测试点时限 |
1 秒 |
1 秒 |
1 秒 |
内存限制 |
512MB |
512MB |
512MB |
测试点数目 |
10 |
10 |
10 |
每个测试点分值 |
10 |
10 |
10 |
是否有部分分 |
无 |
无 |
无 |
题目类型 |
传统 |
传统 |
传统 |
他
【问题描述】
一张长度为N的纸带, 我们可以从左至右编号为0 − N( 纸带最左端标号为
0)。 现在有M次操作, 每次将纸带沿着某个位置进行折叠,
问所有操作之后纸带
的长度是多少。
【输入格式】
第一行两个数字N, M如题意所述。
接下来一行M个整数代表每次折叠的位置。
【输出格式】
一行一个整数代表答案。
【样例输入】
5 2
3 5
【样例输出】
2
【样例解释】
树上有只鸟。
【数据规模与约定】
对于60%的数据, N, M ≤ 3000。
对于100%的数据, N ≤ 10^18, M ≤ 3000。
她
【问题描述】
给你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。
它
【问题描述】
N个人坐成一圈, 其中第K个人拿着一个球。 每次每个人会以一定的概率向
左边的人和右边的人传球。 当所有人都拿到过球之后, 最后一个拿到球的人即为
胜者。 求第N个人获胜的概率。( 所有人按照编号逆时针坐成一圈)
【输入格式】
第一行一个数T代表数据组数。
对于每组数据, 第一行两个整数N, K如题意所述。
接下来每行一个实数p代表该人将球传给右边的人的概率。
【输出格式】
对于每组数据, 一行一个实数代表答案, 保留9位小数。
【样例输入】
1
5 1
0.10
0.20
0.30
0.40
0.50
【 样例输出】
0.007692308
【 样例解释】
然后鸟是我的。
【数据规模与约定】
对于20%的数据, N ≤ 3。
对于70%的数据, T, N ≤ 100。
对于100%的数据, T ≤ 10000,1 ≤ N ≤ 100。
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术