2023.5.19测试
T1 数
唯一会的题
设
我们又知道
直接根号枚举
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int T;
LL g,l;
LL gcd(LL a,LL b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&g,&l);
if(l%g!=0)
{
printf("-1\n");
continue;
}
LL k=l/g,ans=1e15;
for(LL i=1; i<=sqrt(k); i++)
{
if(k%i!=0)
continue;
LL a=i,b=k/i;
if(gcd(a,b)==1)
ans=min(ans,a+b);
}
printf("%lld\n",ans*g);
}
return 0;
}
T2 兼容
有
考场没有考虑
变换一下式子,不兼容的情况为
所以两种物品不兼容的前提是
那么问题就很简单了,对于最简的
最后
考场上以为这样能
我们将所有物品分为四类:
均为 ,数量记为 为 ,但 不为 ,数量记为 不为 ,但 为 ,数量记为 均不为 ,数量记为
对于第四种我们像上述那样计算。第二和第三种即让
综上,这是一道sb细节计数题:)
#include<bits/stdc++.h>
#define LL long long
#define mp make_pair
using namespace std;
const int N=200010;
const LL MOD=1000000007;
struct node
{
LL x,y;
}a[N];
int n,v[N];
LL ans=1,A,B,C,D;
map <pair<LL,LL>,int> fa,fb,ida,idb;
LL gcd(LL a,LL b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
LL ksm(int a,int b)
{
if(b==0)
return 1;
if(b==1)
return (LL)a;
LL tmp=ksm(a,b/2);
if(b%2==0)
return tmp*tmp%MOD;
return tmp*tmp%MOD*1LL*a%MOD;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%lld%lld",&a[i].x,&a[i].y);
if(a[i].x==0 && a[i].y==0)
A++;
else if(a[i].x==0 && a[i].y!=0)
B++;
else if(a[i].x!=0 && a[i].y==0)
C++;
else
{
D++;
if((a[i].x>0 && a[i].y>0) || (a[i].x<0 && a[i].y<0))
{
v[i]=1;
a[i].x=abs(a[i].x); a[i].y=abs(a[i].y);
LL d=gcd(a[i].x,a[i].y);
a[i].x/=d; a[i].y/=d;
pair<LL,LL> tmp=mp(a[i].x,a[i].y);
if(fa[tmp])
v[i]=0;
else
ida[tmp]=i;
fa[tmp]++;
}
else
{
v[i]=-1;
a[i].x=abs(a[i].x); a[i].y=abs(a[i].y);
LL d=gcd(a[i].x,a[i].y);
a[i].x/=d; a[i].y/=d;
pair<LL,LL> tmp=mp(a[i].x,a[i].y);
if(fb[tmp])
v[i]=0;
else
idb[tmp]=i;
fb[tmp]++;
}
}
}
for(int i=1; i<=n; i++)
{
if(!v[i])
continue;
pair<LL,LL> cur=mp(a[i].x,a[i].y);
if(v[i]>0)
{
pair<LL,LL> tur=mp(a[i].y,a[i].x);
int cnta=fa[cur],cntb=fb[tur];
if(cntb==0)
(ans*=ksm(2,cnta))%=MOD;
else
(ans*=(ksm(2,cnta)+ksm(2,cntb)-1)%MOD)%=MOD;
v[i]=v[idb[tur]]=0;
}
else
{
pair<LL,LL> tur=mp(a[i].y,a[i].x);
int cnta=fb[cur],cntb=fa[tur];
if(cntb==0)
(ans*=ksm(2,cnta))%=MOD;
else
(ans*=(ksm(2,cnta)+ksm(2,cntb)-1)%MOD)%=MOD;
v[i]=v[ida[tur]]=0;
}
}
if(!B && C)
(ans*=ksm(2,C))%=MOD;
else if(B && !C)
(ans*=ksm(2,B))%=MOD;
else if(B && C)
(ans*=(ksm(2,B)+ksm(2,C)-1)%MOD)%=MOD;
(ans-=1-MOD)%=MOD; //警钟敲响
(ans+=A)%=MOD;
printf("%lld",ans);
return 0;
}
T3 面积
一个平面直角坐标系,INF
不会,只会输出
好吧我是小丑
将坐标离散化后就会出现很多被线段分割出来的矩形,用一个差分把所有线段的坐标转移到新的坐标上,然后直接搜索即可
因为求的是面积,我们不在点上面走,而在格子上面走,用格子右上角的坐标表示这个格子,这样可以方便计算
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=3010;
struct node
{
int a,b,c;
}s1[N],s2[N];
int n,m,bx[N],by[N],tx,ty,nx,ny;
int r[N][N],c[N][N];
LL ans;
bool v[N][N];
void dfs(int x,int y)
{
if(v[x][y])
return;
if(x<=1 || y<=1 || x>nx || y>ny)
{
printf("INF");
exit(0);
}
v[x][y]=1;
ans+=1LL*(bx[x]-bx[x-1])*(by[y]-by[y-1]);
if(!r[x][y])
dfs(x+1,y);
if(!r[x-1][y])
dfs(x-1,y);
if(!c[y][x])
dfs(x,y+1);
if(!c[y-1][x])
dfs(x,y-1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%d%d%d",&s1[i].a,&s1[i].b,&s1[i].c);
bx[++tx]=s1[i].a; bx[++tx]=s1[i].b;
by[++ty]=s1[i].c;
}
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&s2[i].a,&s2[i].b,&s2[i].c);
by[++ty]=s2[i].b; by[++ty]=s2[i].c;
bx[++tx]=s2[i].a;
}
bx[++tx]=0; by[++ty]=0;
sort(bx+1,bx+1+tx);
sort(by+1,by+1+ty);
nx=unique(bx+1,bx+1+tx)-(bx+1);
ny=unique(by+1,by+1+ty)-(by+1);
for(int i=1; i<=n; i++)
{
s1[i].a=lower_bound(bx+1,bx+1+nx,s1[i].a)-bx;
s1[i].b=lower_bound(bx+1,bx+1+nx,s1[i].b)-bx;
s1[i].c=lower_bound(by+1,by+1+ny,s1[i].c)-by;
c[s1[i].c][s1[i].a+1]++; //注意差分的下标
c[s1[i].c][s1[i].b+1]--;
}
for(int i=1; i<=m; i++)
{
s2[i].a=lower_bound(bx+1,bx+1+nx,s2[i].a)-bx;
s2[i].b=lower_bound(by+1,by+1+ny,s2[i].b)-by;
s2[i].c=lower_bound(by+1,by+1+ny,s2[i].c)-by;
r[s2[i].a][s2[i].b+1]++;
r[s2[i].a][s2[i].c+1]--;
}
for(int i=1; i<=nx; i++)
for(int j=1; j<=ny+1; j++)
r[i][j]+=r[i][j-1];
for(int i=1; i<=ny; i++)
for(int j=1; j<=nx+1; j++)
c[i][j]+=c[i][j-1];
int sx=lower_bound(bx+1,bx+1+nx,0)-bx;
int sy=lower_bound(by+1,by+1+ny,0)-by;
dfs(sx,sy);
printf("%lld",ans);
return 0;
}
T4 中位数
已知
又是一道不会的题,暴力搜索
没想到居然是道数学题
直接给出结论:
将
- 当
是奇数时,设 , - 当
是偶数时,设 ,
下面证明一下当
首先显然
设
,数量记为 ,数量记为
若能取到
sort(a+1,a+1+n);
sort(b+1,b+1+n);
if(n&1)
printf("%d",b[n/2+1]-a[n/2+1]+1);
else
printf("%d",b[n/2+1]+b[n/2]-a[n/2+1]-a[n/2]+1);
T5 网格
一个
- 若处在第
列或第 行,则向下/向右走一步 - 否则,往下和右数字大的地方走,相同则往右走
问从左上角走到右下角,途中经过的格子数字和为
非常困难的
首先有个朴素的
时间复杂度
不过我们主要讲另一种方法,就是将路径和填数分开考虑
设
容易发现,当到达第
因此,我们设
对于最后单向移动的那部分,我们设
那么最后我们枚举到达的点
时间复杂度
总的来说,要想到将填数和路径分离,并且以最后的行和列作为突破口,将前后两段分开,是这道题制胜的关键。果然还是太菜了,考场上甚至没去写朴素的
#include<bits/stdc++.h>
using namespace std;
const int N=2510,M=110;
const int MOD=10007;
int n,m,s,pw[N],ans;
int f[N][N],g[N][M];
int e[N][M],h[N][M],ee[N][M],hh[N][M];
void prework()
{
pw[0]=1;
for(int i=1; i<=max(n,m); i++)
pw[i]=1LL*pw[i-1]*(s+1)%MOD;
ee[0][0]=1;
for(int i=1; i<n; i++)
for(int j=0; j<=s; j++)
for(int k=0; k<=j; k++)
(ee[i][j]+=ee[i-1][j-k]*k%MOD)%=MOD;
hh[0][0]=1;
for(int i=1; i<m; i++)
for(int j=0; j<=s; j++)
for(int k=0; k<=j; k++)
(hh[i][j]+=hh[i-1][j-k]*(k+1)%MOD)%=MOD;
}
signed main()
{
scanf("%d%d%d",&n,&m,&s);
if(n==1 && m==1 && s==0)
{
printf("1");
return 0;
}
prework();
for(int i=0; i<=s; i++)
e[0][i]=ee[n-1][i];
for(int i=1; i<m; i++)
for(int j=0; j<=s; j++)
for(int k=0; k<=j; k++)
(e[i][j]+=e[i-1][j-k]*(k+1)%MOD)%=MOD;
for(int i=0; i<=s; i++)
h[0][i]=hh[m-1][i];
for(int i=1; i<n; i++)
for(int j=0; j<=s; j++)
for(int k=0; k<=j; k++)
(h[i][j]+=h[i-1][j-k]*k%MOD)%=MOD;
g[0][0]=1;
for(int i=1; i<=max(n,m); i++)
for(int j=0; j<=s; j++)
for(int k=0; k<=j; k++)
(g[i][j]+=g[i-1][j-k])%=MOD;
f[1][1]=1;
for(int i=1; i<n; i++)
{
for(int j=1; j<m; j++)
f[i][j]+=(1LL*f[i-1][j]*pw[m-j-1]%MOD+1LL*f[i][j-1]*pw[n-i-1]%MOD)%MOD;
f[i][m]+=1LL*f[i][m-1]*pw[n-i-1]%MOD;
for(int j=0; j<=s; j++)
(ans+=1LL*f[i][m]*h[i-1][j]%MOD*g[n-i][s-j]%MOD)%=MOD;
}
for(int i=1; i<m; i++)
f[n][i]+=1LL*f[n-1][i]*pw[m-i-1]%MOD;
for(int i=1; i<m; i++)
for(int j=0; j<=s; j++)
(ans+=1LL*f[n][i]*e[i-1][j]%MOD*g[m-i][s-j]%MOD)%=MOD;
printf("%d",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效