• Educational Codeforces Round 78 (Rated for Div. 2)


    A.Shuffle Hashing

    题意:给定s1,s2两个字符串。问s2中是否有s1不计顺序的字串。

    题解:sort就完事了,比较一下就好。

    贴dalao代码

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int main() {
     4     int t;
     5     cin >> t;
     6     while (t--) {
     7         string s1, s2;
     8         cin >> s1 >> s2;
     9         sort(s1.begin(), s1.end());
    10         string ans = "NO";
    11         for (int i = 0; i + s1.size() <= s2.size(); ++i) {
    12             auto d = s2.substr(i, s1.size());
    13             sort(d.begin(), d.end());
    14             if (s1 == d) {
    15                 ans = "YES";
    16                 break;
    17             }
    18         }
    19         cout << ans << "
    ";
    20     }
    21     return 0;
    22 }

    B - A and B

    题意:给定两个数字,可以进行操作,给其中一个数+1,下次给其中一个数+2,以此类推,求最小操作数。

    题解:num为abs两数之差,转化为可对num操作,加一或减一,加二或减二...

       考虑在1,2,...n每个数前面加正号或负号,所得最大的数为n*(n+1)/2,显然num必须小于n*(n+1)/2,

       考虑改变1,2..n某个数k前的符号,总的结果会改变2*k,所以通过改变符号可以遍历-n*(n+1)/2到n*(n+1)/2中所有奇偶性和n*(n+1)/2相同的数

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int t,a,b;
     4 int main()
     5 {
     6     cin>>t;
     7     while(t)
     8     {
     9         t--;
    10         cin>>a>>b;
    11         int num=abs(a-b);int ans=0;
    12         while(ans*(ans+1)/2<num||(ans*(ans+1)/2-num)%2)
    13         ans++;
    14         cout<<ans<<endl;
    15     }
    16 }

    C - Berry Jam

    题意:给定2*n个12序列,从n和n+1之间可以任意往左和往右删除任意长度,使得剩下的12个数相等,求min删除个数。

    题解:考虑贡献,维护一个前缀和,1的贡献为1,2为-1,删除左边部分的前缀和和右边的后缀和为相反数即可。

       维护一个pos数组,pos【i】表示前缀和为i的位置。

       然后我们从n位置开始枚举就可以了,查找可以用map(stl大法好)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int t,n;
     4 int pre[300000];
     5 int main()
     6 {
     7     cin>>t;
     8     while(t--)
     9     {
    10         cin>>n;int a;map<int,int>pos;
    11         pos[0]=0;
    12         for(int i=1;i<=2*n;i++)
    13         {
    14             cin>>a;pre[i]=pre[i-1]+(a==1?1:-1);
    15             if(i<=n)pos[pre[i]]=i;
    16         }
    17         int ans=2*n;
    18         for(int i=n;i<=2*n;i++)
    19         {
    20             map<int,int>::iterator it=pos.find(pre[i]-pre[n*2]);    
    21             if(it!=pos.end()) ans=min(ans,i-it->second);
    22         }
    23         cout<<ans<<endl;
    24     }
    25 }

    D.Segment Tree

    题意:给定n个区间,i点和j点连接当且仅当区间i和区间j有交集且其中一个不被另一个完全包括。问是否能组成树。

    题解:判断是否连了n-1条边。用并查集维护,如果合并前二者已在一个集合,则连成了环。

       问题就在于如何判断两个点是否相连。

       暴力n^2枚举,5*1e5就算是2s也是tle的死死的。

       可以按左端点排序,开一个set维护右端点,二分查找大于等于当前左端点的set元素,然后往后看,大于当前右节点就退出,否则合并,最后把当前右节点插进去。

        详见代码。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 int f[2*600000];
     5 int find(int x){return f[x]==x?x:find(f[x]);}
     6 void merge(int x,int y){f[find(x)]=f[find(y)];}
     7 struct data{int l,r;}a[600000];
     8 bool cmp(data a,data b){return a.l<b.l;}
     9 set<int> s;
    10 int main()
    11 {
    12     scanf("%d",&n);int ent=0;
    13     for(int i=1;i<=n;i++)scanf("%d%d",&a[i].l,&a[i].r),f[i]=i,f[i+n]=i+n;
    14     sort(a+1,a+1+n,cmp);
    15     for(int i=1;i<=n;i++)
    16     {
    17         set<int>::iterator it=s.lower_bound(a[i].l);
    18         for(;it!=s.end()&&*it<a[i].r;it++)
    19         {
    20             if(find(*it)==find(a[i].r))return !printf("NO
    ");
    21             merge(*it,a[i].r);
    22             ent++;
    23         }
    24         s.insert(a[i].r);
    25     }
    26     ent==n-1?cout<<"YES":cout<<"NO";
    27     return 0;
    28 }

    后面的回头再补

  • 相关阅读:
    go正则解析log文件
    go的堆排序
    golang实现websocket
    golang接口
    erlang时间操作
    golang函数
    golang for循环
    golang 条件语句if,switch
    golang内建变量类型
    区间存在幂个数
  • 原文地址:https://www.cnblogs.com/mjc191812/p/12076499.html
Copyright © 2020-2023  润新知