2025省选模拟8
2025省选模拟8
题目来源: 2024省选联测10
HZTG5836. 小幸运
-
将坐标扩大
倍后答案只可能为整数,证明显然。 -
二分答案,
时考虑 。 -
将一个点可能构成的等腰直角三角形划分成如下四个部分,最终仅能选择相邻的两个。不妨两条对角线上的取值分开考虑,然后进行合并。
-
现在就只需要解决判断两个三角形是否相交的问题了。
-
容易想到的思路是根据两个三角形相交必然有两条边相交,枚举
种匹配情况进行判断某两条线段是否有交点,需要特判斜率不存在的情况。因本题 相交 定义的特殊性,需要适当调整边界是否取到的情况。 -
挂两组三角形完全相等的 Corner Case ,数据没卡这个方面。
点击查看数据
in: 2 100 100 1 1 50 50 ans: 2
in: 2 100 100 0 0 50 50 ans: 0
点击查看代码
const ll dx[4][3]={{1,0,0},{1,0,0},{-1,0,0},{-1,0,0}},dy[4][3]={{0,-1,0},{0,1,0},{0,-1,0},{0,1,0}}; ll dfn[510],low[510],ins[510],col[510],x[2][3],y[2][3],tot,scc_cnt,n,w,h; pair<ll,ll>a[510],z[2][3]; stack<ll>s; vector<ll>e[510]; void add(ll u,ll v) { e[u].push_back(v); } void tarjan(ll x) { tot++; dfn[x]=low[x]=tot; ins[x]=1; s.push(x); for(ll i=0;i<e[x].size();i++) { if(dfn[e[x][i]]==0) { tarjan(e[x][i]); low[x]=min(low[x],low[e[x][i]]); } else { if(ins[e[x][i]]==1) { low[x]=min(low[x],dfn[e[x][i]]); } } } if(dfn[x]==low[x]) { scc_cnt++; ll tmp=0; while(x!=tmp) { tmp=s.top(); ins[tmp]=0; col[tmp]=scc_cnt; s.pop(); } } } bool out_of_bounds(ll x,ll y,ll op,ll mid) { for(ll i=0;i<=1;i++) { if(x+dx[op][i]*mid<0||x+dx[op][i]*mid>w||y+dy[op][i]*mid<0||y+dy[op][i]*mid>h) return true; } return false; } bool line_cross(ll x1,ll y1,ll x2,ll y2,ll _x1,ll _y1,ll _x2,ll _y2) { if(x1==x2&&_x1==_x2) { return ((x1==_x1)&&((min(y1,y2)<_y1&&_y1<max(y1,y2))||(min(y1,y2)<_y2&&_y2<max(y1,y2)))); } if(_x1==_x2) { swap(x1,_x1); swap(y1,_y1); swap(x2,_x2); swap(y2,_y2); } if(x1==x2) { double _k=1.0*(_y2-_y1)/(_x2-_x1),_b=_y1-_x1*_k,y=_k*x1+_b; return (_x1<x1&&x1<_x2&&min(y1,y2)<y&&y<max(y1,y2)); } double k=1.0*(y2-y1)/(x2-x1),b=y1-x1*k,_k=1.0*(_y2-_y1)/(_x2-_x1),_b=_y1-_x1*_k; if(k==_k) return false; double x=(_b-b)/(k-_k); return (min(x1,x2)<x&&x<max(x1,x2)&&min(_x1,_x2)<x&&x<max(_x1,_x2)); } bool triangle_cross(ll x1,ll y1,ll op1,ll x2,ll y2,ll op2,ll mid) { for(ll i=0;i<=2;i++) { x[0][i]=x1+dx[op1][i]*mid; y[0][i]=y1+dy[op1][i]*mid; x[1][i]=x2+dx[op2][i]*mid; y[1][i]=y2+dy[op2][i]*mid; } for(ll i=0;i<=2;i++) { for(ll j=0;j<=2;j++) { if(line_cross(x[0][i],y[0][i],x[0][(i+1)%3],y[0][(i+1)%3], x[1][j],y[1][j],x[1][(j+1)%3],y[1][(j+1)%3])==true) { return true; } } } return false; } bool check(ll mid) { for(ll i=1;i<=8*n;i++) e[i].clear(); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(ins,0,sizeof(ins)); memset(col,0,sizeof(col)); tot=scc_cnt=0; while(s.empty()==0) s.pop(); for(ll i=1;i<=n;i++) { for(ll j=0;j<=3;j++) { add(i+j*n,i+(3-j)*n+4*n); add(i+j*n+4*n,i+(3-j)*n); if(out_of_bounds(a[i].first,a[i].second,j,mid)==true) add(i+j*n,i+j*n+4*n); } } for(ll i=1;i<=n;i++) { for(ll j=i+1;j<=n;j++) { for(ll u=0;u<=3;u++) { for(ll v=0;v<=3;v++) { if((a[i]==a[j]&&u==v)||triangle_cross(a[i].first,a[i].second,u, a[j].first,a[j].second,v,mid)==true) { add(i+u*n,j+v*n+4*n); add(j+v*n,i+u*n+4*n); } } } } } for(ll i=1;i<=8*n;i++) if(dfn[i]==0) tarjan(i); for(ll i=1;i<=4*n;i++) if(col[i]==col[i+4*n]) return false; return true; } int main() { #define Isaac #ifdef Isaac freopen("lucky.in","r",stdin); freopen("lucky.out","w",stdout); #endif ll l=0,r,ans=0,mid,i; cin>>n>>w>>h; r=min(w,h); w*=2; h*=2; for(i=1;i<=n;i++) { cin>>a[i].first; a[i].first*=2; } for(i=1;i<=n;i++) { cin>>a[i].second; a[i].second*=2; } while(l<=r) { mid=(l+r)/2; if(check(mid)==true) { ans=mid; l=mid+1; } else { r=mid-1; } } cout<<ans<<endl; return 0; }
HZTG5837. 山河入梦来
-
部分分
:枚举全排列。
点击查看代码
int l[100010],r[100010],p[100010],s[2]; int main() { #define Isaac #ifdef Isaac freopen("river.in","r",stdin); freopen("river.out","w",stdout); #endif int t,n,op,i,j; scanf("%d",&t); for(;t>=1;t--) { s[0]=s[1]=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d%d",&l[i],&r[i]); for(i=1;i<=n;i++) p[i]=i; do { for(i=1;i<=n;i++) { if(!(l[i]<=p[i]&&p[i]<=r[i])) break; } if(i==n+1) { op=0; for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(p[j]<p[i]) op^=1; } } s[op]++; } }while(next_permutation(p+1,p+1+n)); if(s[0]==s[1]) printf("tie\n"); if(s[0]>s[1]) printf("pp\n"); if(s[0]<s[1]) printf("xx\n"); } return 0; }
-
正解
- 定义
后只需要求出行列式的正负性即可,但我不会行列式。 - 对于第
行,当 时交换 至多增加 /减少 个逆序对,即只会改变逆序对的奇偶性。此时这种选择对最终结果的取值没有影响。- 证明考虑
内元素产生的逆序对数量不变,分讨大小情况即可。
- 证明考虑
- 观察到对于同一个左端点
的若干个右端点 ,类似上述分析得到只有 时才可能对答案产生影响,否则可以与上面的进行交换从而对最终结果不产生影响。使用可并堆加速堆的合并。 - 最后对构造出来的
再求一遍逆序对,判断奇偶性即可。- 构造
的过程本质上是在顺次考虑 填到何处时才可能对答案产生影响,而这本身就具有唯一性。
- 构造
- 更新过程中若
时输出tie
。前者是因为无法构造出一种合法的 ,后者分析同上。
点击查看代码
int p[100010]; struct BIT { int c[100010]; int lowbit(int x) { return (x&(-x)); } void clear() { memset(c,0,sizeof(c)); } void add(int n,int x,int val) { for(int i=x;i<=n;i+=lowbit(i)) c[i]+=val; } int getsum(int x) { int ans=0; for(int i=x;i>=1;i-=lowbit(i)) ans+=c[i]; return ans; } }B; struct Heap { int root[100010]; struct Leftist_Tree { int ls,rs,val,d; }tree[100010]; #define lson(rt) (tree[rt].ls) #define rson(rt) (tree[rt].rs) void clear() { memset(root,0,sizeof(root)); memset(tree,0,sizeof(tree)); } void build_rt(int rt,int val) { lson(rt)=rson(rt)=0; tree[rt].val=val; tree[rt].d=1; } int merge(int rt1,int rt2) { if(rt1==0||rt2==0) return rt1+rt2; if(tree[rt1].val>tree[rt2].val) swap(rt1,rt2); rson(rt1)=merge(rson(rt1),rt2); if(tree[lson(rt1)].d<tree[rson(rt1)].d) swap(lson(rt1),rson(rt1)); tree[rt1].d=tree[rson(rt1)].d+1; return rt1; } void del(int &rt) { rt=merge(lson(rt),rson(rt)); } int query(int rt) { return tree[rt].val; } }T; int main() { #define Isaac #ifdef Isaac freopen("river.in","r",stdin); freopen("river.out","w",stdout); #endif int t,n,l,r,ans,flag,i; scanf("%d",&t); for(;t>=1;t--) { ans=flag=0; B.clear(); T.clear(); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d",&l,&r); p[i]=i; T.build_rt(i,r); T.root[l]=T.merge(T.root[l],i); } for(i=1;i<=n&&flag==0;i++) { if(T.root[i]==0) flag=1; r=T.query(T.root[i]); p[T.root[i]]=i; T.del(T.root[i]); if(T.root[i]!=0&&T.query(T.root[i])==r) flag=1; T.root[r+1]=T.merge(T.root[r+1],T.root[i]); } for(i=n;i>=1;i--) { ans=(ans+B.getsum(p[i]-1))%2; B.add(n,p[i],1); } if(flag==1) printf("tie\n"); else if(ans%2==0) printf("pp\n"); else printf("xx\n"); } return 0; }
- 定义
HZTG5838. 遇见
总结
以为只能朝上、朝右放,还口胡了个判断两个三角形相交时只取三个端点判是否在另一个三角形内部。在过掉大样例后以为直接切了,遂没再管。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18686822,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下