11.3 模拟赛
写了300分得了120 被众多低年级大佬的暴力踩成了弱智
T1 avogadro
题目大意:
3行N列 第一行为N的排列 其余两行的数属于$[1,n]$
求最少删除多少列使剩下的列中 三行排序后一样
思路:
找到第二行或第三行里没有的 然后像拓扑一样搞就行了
(写的贼丑)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 200100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 //yyc score=0 22 int n,a[MAXN][3],hsh[MAXN],cnt[MAXN][3]; 23 int vis[MAXN],q[MAXN],l=1,r,ans; 24 int main() 25 { 26 freopen("avogadro.in","r",stdin); 27 freopen("avogadro.out","w",stdout); 28 n=read();int b,c; 29 for(int i=1;i<=n;i++) a[i][0]=read(),hsh[a[i][0]]=i; 30 for(int i=1;i<=n;i++) a[i][1]=read(),cnt[a[i][1]][1]++; 31 for(int i=1;i<=n;i++) a[i][2]=read(),cnt[a[i][2]][2]++; 32 for(int i=1;i<=n;i++) 33 if((!cnt[i][1]||!cnt[i][2])&&!vis[hsh[i]]) vis[hsh[i]]=1,q[++r]=hsh[i]; 34 while(l<=r) 35 { 36 c=q[l++],cnt[a[c][1]][1]--,cnt[a[c][2]][2]--; 37 if(!vis[hsh[a[c][1]]]&&!cnt[a[c][1]][1]) vis[hsh[a[c][1]]]=1,q[++r]=hsh[a[c][1]]; 38 if(!vis[hsh[a[c][2]]]&&!cnt[a[c][2]][2]) vis[hsh[a[c][2]]]=1,q[++r]=hsh[a[c][2]]; 39 } 40 for(int i=1;i<=n;i++) if(vis[i]) ans++; 41 printf("%d",ans); 42 }
T2 connect
题目大意:
N个点($n\le9$) M条边 每条边有$p_i$的概率消失
求所有点联通的概率
思路:
阶乘状压表示集合裸题
(但是忘记这是个二维dp导致算重了,而且转换也非常菜的算错了)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 380100 13 #define MOD 1000000007 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 20 return x*f; 21 } 22 //yyc score=0 23 int n,m,lm[12],u[100],v[100],no[MAXN],g[MAXN][12],t[12]; 24 double w[100],dp[MAXN],gr[MAXN]; 25 inline int calc() 26 { 27 int res=0; 28 for(int i=1;i<=n;i++) res+=(t[i]-1)*(lm[n]/lm[i]); 29 return res+1; 30 } 31 int main() 32 { 33 freopen("connect.in","r",stdin); 34 freopen("connect.out","w",stdout); 35 n=read(),m=read(); 36 for(int i=1;i<=m;i++) 37 { 38 u[i]=read(),v[i]=read(); 39 scanf("%lf",&w[i]); 40 } 41 for(int i=lm[0]=1;i<=n;i++) lm[i]=lm[i-1]*i; 42 for(int i=1;i<=n;i++) g[1][i]=1; 43 for(int i=2,x;i<=lm[n];i++) 44 { 45 x=n; 46 while(1) 47 { 48 g[i][x]=g[i-1][x]+1; 49 if(g[i][x]>x) g[i][x]=1,g[i][x-1]++; 50 else break; 51 x--; 52 } 53 for(int j=1;j<x;j++) g[i][j]=g[i-1][j]; 54 } 55 dp[lm[n]]=1.0; 56 for(int i=1;i<=m;i++) 57 { 58 for(int j=1;j<=lm[n];j++) 59 if(dp[j]) 60 { 61 for(int k=1;k<=n;k++) t[k]=g[j][k]; 62 for(int k=1;k<=n;k++) if(g[j][v[i]]==t[k]||t[k]==g[j][u[i]]) t[k]=min(g[j][u[i]],g[j][v[i]]); 63 gr[calc()]+=dp[j]*(1-w[i]),gr[j]+=dp[j]*w[i]; 64 } 65 for(int j=1;j<=lm[n];j++) dp[j]=gr[j],gr[j]=0; 66 } 67 printf("%.3lf\n",dp[1]); 68 }
T3 dist
题目大意:
网格图上有一些点为黑点 M次询问 每次询问一个坐标离它最近的黑点的欧几里得距离
思路:
考场上没想那么多 KD tree莽就完事了
(结果估价函数写挂了)
正解是对每行处理斜率优化推一推式子
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 2500100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 //yyc score=0 22 int n,tot,dim,m; 23 char ch[2010][2010]; 24 struct node {int d[2],mn[2],mx[2],l,r;}; 25 bool cmp (const node &a,const node &b) {return a.d[dim]<b.d[dim];} 26 inline int sqr(int x) {return x*x;} 27 struct kd_tree 28 { 29 node tr[MAXN],l,r,g; 30 int rt,ans; 31 inline void upd(int k) 32 { 33 l=tr[tr[k].l],r=tr[tr[k].r]; 34 for(int i=0;i<2;i++) 35 { 36 if(tr[k].l) tr[k].mn[i]=min(tr[k].mn[i],l.mn[i]),tr[k].mx[i]=max(tr[k].mx[i],l.mx[i]); 37 if(tr[k].r) tr[k].mn[i]=min(tr[k].mn[i],r.mn[i]),tr[k].mx[i]=max(tr[k].mx[i],r.mx[i]); 38 } 39 } 40 inline int get(int k) 41 { 42 int res=0; 43 for(int i=0;i<2;i++) 44 res+=sqr(max(max(0,tr[k].mn[i]-g.d[i]),max(0,g.d[i]-tr[k].mx[i]))); 45 return res; 46 } 47 inline int dis(int k) 48 { 49 int res=0; 50 for(int i=0;i<2;i++) 51 res+=sqr(tr[k].d[i]-g.d[i]); 52 return res; 53 } 54 int build(int l,int r,int D) 55 { 56 dim=D;int mid=l+r>>1; 57 nth_element(tr+l,tr+mid,tr+r+1,cmp); 58 for(int i=0;i<2;i++) tr[mid].mn[i]=tr[mid].mx[i]=tr[mid].d[i]; 59 if(l<mid) tr[mid].l=build(l,mid-1,D^1); 60 if(mid<r) tr[mid].r=build(mid+1,r,D^1); 61 upd(mid);return mid; 62 } 63 int query(int k) 64 { 65 int dl=inf,dr=inf; 66 ans=min(ans,dis(k)); 67 if(tr[k].l) dl=get(tr[k].l); 68 if(tr[k].r) dr=get(tr[k].r); 69 if(dl>dr) 70 { 71 if(dr<ans) query(tr[k].r); 72 if(dl<ans) query(tr[k].l); 73 } 74 else 75 { 76 if(dl<ans) query(tr[k].l); 77 if(dr<ans) query(tr[k].r); 78 } 79 } 80 }K; 81 int main() 82 { 83 freopen("dist.in","r",stdin); 84 freopen("dist.out","w",stdout); 85 n=read(); 86 for(int i=0;i<n;i++) 87 { 88 scanf("%s",ch[i]); 89 for(int j=0;j<n;j++) if(ch[i][j]=='1') K.tr[++tot].d[0]=i,K.tr[tot].d[1]=j; 90 } 91 n=tot,m=read(); 92 K.rt=K.build(1,n,0); 93 while(m--) 94 { 95 K.g.d[0]=read()-1,K.g.d[1]=read()-1; 96 if(ch[K.g.d[0]][K.g.d[1]]=='1') {puts("0");continue;} 97 K.ans=inf;K.query(K.rt); 98 printf("%d\n",K.ans); 99 } 100 }