zoukankan      html  css  js  c++  java
  • AcWing周赛 1

    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 }
  • 相关阅读:
    HDU1196 ZOJ2417 Lowest Bit
    HDU1008 ZOJ2108 Elevator
    HDU2614 Beat
    HDU2057 A + B Again
    POJ3984 迷宫问题
    HDU1013 POJ1519 Digital Roots
    HDU2051 Bitset
    HDU2037 今年暑假不AC
    ACM入门练习与递推小结
    HDU2046 骨牌铺方格【递推】
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14836916.html
Copyright © 2011-2022 走看看