暑假集训7月18日
E - Dist Max 2
找最小值的最大值,这种题目一般都是二分

#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10,inf=0x3f3f3f3f; struct node { int x,y; }a[N]; int n; bool cmp(node a,node b) { if (a.x!=b.x)return a.x<b.x; else return a.y<b.y; } bool check(int mid) { int l=1; int mi=inf,ma=0; for (int i=1;i<=n;i++) { while (l<=n&&abs(a[i].x-a[l].x)>=mid) { mi=min(mi,a[l].y),ma=max(ma,a[l++].y); } if (a[i].y-mi>=mid||ma-a[i].y>=mid) return true; } return false; } signed main() { scanf("%d",&n); for (int i=1;i<=n;i++) cin>>a[i].x>>a[i].y; sort(a+1,a+n+1,cmp); int l=0,r=inf; while (l<r) { int mid=(l+r+1)>>1; if (check(mid))l=mid; else r=mid-1; } printf("%d\n",l); return 0; }
check函数就是要判断是否有两个点满足m i n ( x i − x j , y i − y j ) > = m i d ,因为要找的是最小的最大值,就要尽可能往右找,min>=mid说明答案在右边,所以mid的取值要往右,l=mid,前面小的就不满足,区间就往右边缩。
要找两个点,先固定i点,然后去找j点。枚举i点的时候,对每一个i点枚举j点。因为只有xi-xj>=mid的时候,才需要考虑m i n ( x i − x j , y i − y j ) 有没有可能在y的时候会被更新到更小,while循环枚举j,在满足m i n ( x i − x j , y i − y j ) > = m i d的条件下,找到最大的和最小的y值,然后分别计算他们与此时的i点的y值的差,while 循环结束的时候满足m i n ( x i − x j , y i − y j ) > = m i d的y的两个最大的差值就找到了,然后看这两个差中有没有哪一个是比mid大,如果大,说明答案还在右边,这个时候返回true,继续把区间往右缩,反之答案在左边,就是往左缩区间,最后l==r的时候,l就是要找的答案。
B - One More aab aba baa
和全排列一样,但是会有重复的情况出现,所以要去重。用set去重,貌似它是会自己从小到大排。
#include <iostream> #include <math.h> #include <algorithm> #include <cstring> #include <string.h> #include <set> using namespace std; const int N = 5e5+10; int idx; char fa[10]; string a[N],aa; set<string> q; int x, len, vis[10],n; char s[10]; void dfs(int u) { if(u==len) { aa= ""; for(int i=0; i<len; i++) { aa += fa[i]; } q.insert(aa); return ; } for(int i = 0; i<len; i++) { if(!vis[i]) { fa[u] = s[i]; vis[i] = 1; dfs(u+1); vis[i] = 0; } } } int main() { char ch; scanf("%s %d",s,&n); len = strlen(s); dfs(0); int x= 0; for(auto item: q) { x++; if(x==n) cout<<item<<endl; } return 0; }
C - Coprime 2
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; int a[N],prime[N]; bool st[N]; int n,m,cnt,k; void div(int x) { for (int i=2; i<=x/i; i++) { if (x%i==0) { int s=0; while (x%i==0) { x/=i; s++; } if (i>1) { st[i]=1; } if (s>1) { st[s]=1; } } } if (x>1) { st[x]=1; } } void judge() { for (int i=2; i<=m; i++)//筛掉因数的倍数 { if (st[i]) { k++; int j=i; while (j<=m) { st[j]=true; j+=i; } } } } signed main() { scanf("%d%d",&n,&m); for (int i=0; i<n; i++) { scanf("%d",&a[i]); div(a[i]); } judge(); printf("%d\n",m-k); for (int i=1; i<=m; i++) if (!st[i])printf("%d\n",i); return 0; }

浙公网安备 33010602011771号