A:水题。
给定两个数组,找到从这俩数组中各找一数,使得和不在任何一个数组中。
因为数组中的数都是正整数,最大的俩数相加必然不在这俩数组之中。
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 110; 6 int a[N],b[N]; 7 int main() 8 { 9 int n,m; 10 cin>>n; 11 for(int i=0;i<n;i++) 12 cin>>a[i]; 13 cin>>m; 14 for(int j=0;j<m;j++) 15 cin>>b[j]; 16 sort(a,a+n); 17 sort(b,b+m); 18 cout<<a[n-1]<<" "<<b[m-1]<<endl; 19 return 0; 20 }
B:给定一个数组和一个操作次数,每次操作将某一个数加一,问中位数最大为多少。
可以发现只和排序数组的后半部分有关。
解法1:二分,时间复杂度为nlog(n)。
可以观察到随着操作次数的增加,中位数的数值单调增加。
故二分中位数的数值,通过操作次数与k进行比较进行判断。
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 typedef long long LL; 6 const LL N=2e5+10; 7 LL w[N]; 8 LL n,k; 9 bool check(int mid){ 10 LL res=0; 11 for(int i=n/2;i<n;i++){ 12 if(w[i]<mid) 13 res+=mid-w[i]; 14 } 15 return res<=k; 16 } 17 int main() 18 { 19 cin>>n>>k; 20 for(int i=0;i<n;i++) cin>>w[i]; 21 sort(w,w+n); 22 LL l=0,r=2e9; 23 while(l<r){ 24 LL mid=l+r+1>>1; 25 if(check(mid)) l=mid; 26 else r=mid-1; 27 } 28 cout<<r; 29 return 0; 30 }
解法2:模拟,时间复杂度nlog(n)。
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 typedef long long LL; 6 const LL N=2e5+10; 7 LL a[N],q[N]; 8 LL n,k; 9 int main() 10 { 11 cin>>n>>k; 12 for(int i=1;i<=n;i++){ 13 cin>>a[i]; 14 } 15 sort(a+1,a+1+n); 16 LL pos=(n+1)/2; 17 for(int i=pos+1;i<=n;i++){ 18 q[i]=(a[i]-a[i-1])*(i-pos);//计算出若将pos~i变为a[i]需要再加多少次操作【注意再字】 19 } 20 int res=-1; 21 int i; 22 for(i=pos;i<=n&&k>=q[i];i++){ 23 k-=q[i]; 24 } 25 i--;//-1之后是符合条件的 26 cout<<a[i]+k/(i-pos+1); 27 return 0; 28 }
C:最开始的含有n个元素的数组的序列为1~n,给定一个大小为n的移动数组,假设为5,1,2,4,3,问每个数经过多少次操作能够回来。
比如1,第一次操作到5
第二次操作到3
第三次操作到2
第四次操作到1
将移动数组抽象为图的话。
答案为环的大小。[4,4,4,1,4]
分析到这一步,就可以直接建图,然后tarjan了(我不会)。
又因为每一个点的出度为1,入度也为1,所以每一个环必然是一个连通块,所以本题也可以用并查集来写。
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 2e5+10; 6 int p[N],c[N]; 7 int find(int x){ 8 if(p[x]!=x) 9 p[x]=find(p[x]); 10 return p[x]; 11 } 12 int main() 13 { 14 int T; 15 cin>>T; 16 while(T--){ 17 int n; 18 cin>>n; 19 for(int i=1;i<=n;i++) p[i]=i,c[i]=1; 20 for(int i=1;i<=n;i++){ 21 int x; 22 cin>>x; 23 int fa=find(i); 24 int fb=find(x); 25 p[fa]=fb; 26 if(fa!=fb) 27 c[fb]+=c[fa]; 28 } 29 for(int i=1;i<=n;i++) 30 cout<<c[find(i)]<<" "; 31 cout<<endl; 32 } 33 return 0; 34 }