zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 27

    期末后恢复性训练,结果完美爆炸。。。

    A,题意:2n个人,分成两队,要求无论怎么分配,第一队打赢第二队

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=1000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    int a[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<2*n;i++)scanf("%d",&a[i]);
        sort(a,a+2*n);
        if(a[n-1]==a[n])puts("NO");
        else puts("YES");
        return 0;
    }
    /********************
    
    ********************/

    B题意:有一个6位数,要求改最少的数使得前3个加起来等于后三个加起来

    题解:瞎搞都行,我是直接从0for到1000000找最小

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=1000000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    int a[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        int minn=6;
        for(int i=0;i<1000000;i++)
        {
            int be=i/1000;
            int en=i%1000;
            int sum1=0,sum2=0;
            while(be)
            {
                sum1+=be%10;
                be/=10;
            }
            while(en)
            {
                sum2+=en%10;
                en/=10;
            }
            if(sum1==sum2)
            {
                int di=0,te1=i,te2=n;
                for(int j=0;j<6;j++)
                {
                    if(te1%10!=te2%10)di++;
                    te1/=10;te2/=10;
                }
                minn=min(minn,di);
            }
        }
        printf("%d
    ",minn);
        return 0;
    }
    /********************
    
    ********************/

    C:题意:你有两台电视机,n个节目,从l到r,可以用不同的电视机看两个节目,但是一个节目结束的同时一个节目开始,不能用同一台电视机看

    题解:直接模拟,(刚开始还hash了一下,发现根本没必要,简直是sb)

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    struct point{
        int l,r;
        bool operator <(const point &rhm)const{
            if(l!=rhm.l)return l<rhm.l;
            return r<rhm.r;
        }
    }p[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d%d",&p[i].l,&p[i].r);
        sort(p,p+n);
        int t1=-1,t2=-1;
        for(int i=0;i<n;i++)
        {
            if(t1<p[i].l)
            {
                t1=p[i].r;
            }
            else
            {
                if(t2<p[i].l)t2=p[i].r;
                else
                {
                    puts("NO");
                    return 0;
                }
            }
        }
        puts("YES");
        return 0;
    }
    /********************
    
    ********************/

    D:题意:你在考驾照,有“限速x,不限速,可以超车,不可以超车”四种牌子,你有6种操作,前面四个和超车和改变速度,问最小的忽略牌子能满足交规的个数

    题解:直接模拟,超车和超速可以分开考虑,超速用栈保存,超车直接加即可

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    #define y1 y2
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=200000+10,inf=0x3f3f3f3f;
    
    struct event{
        int id,sp;
    }e[N];
    int over[N];
    int main()
    {
        int n;
        scanf("%d",&n);
        int cnt1=0,cnt2=0;
        for(int i=0;i<n;i++)
        {
            int a,b=0;
            scanf("%d",&a);
            if(a==1||a==3)scanf("%d",&b);
            if(a==1||a==3||a==5)e[cnt1++]={a,b};
            else over[cnt2++]=a;
        }
        int ans=0,i=cnt2-1;
        while(i>=0)
        {
            if(over[i]==2)
            {
                i--;
                while(i>=0&&over[i]==6)i--,ans++;
            }
            else i--;
        }
        int speed=0;
        stack<int>s;
        for(int i=0;i<cnt1;i++)
        {
            if(e[i].id==1)
            {
                speed=e[i].sp;
                while(!s.empty()&&speed>s.top())
                {
                    s.pop();
                    ans++;
                }
            }
            else if(e[i].id==3)
            {
                s.push(e[i].sp);
                while(!s.empty()&&speed>s.top())
                {
                    s.pop();
                    ans++;
                }
            }
            else
            {
                while(!s.empty())s.pop();
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    /********************
    
    ********************/

    E:题意:有n*m的块,k个点着火了,每分钟一个点扩散到其他八个点,问找一个点,使得的最小扩散全部的时间

    题解:二分答案,判断可行时,先离散化,要注意加上x+q+1的情况,因为中间可能会有两个连起来的情况,然后扫描线跑一边,找没有覆盖的最大矩形,看能不能满足条件

    (由于没有考虑x+q+1的情况,导致花了一个下午找bug = = )

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=5000+10,maxn=4000+10,inf=0x3f3f3f3f;
    
    struct point{
        int x,y;
    }p[N];
    int n,m,k;
    int dp[maxn][maxn];
    bool ok(int q)
    {
        vector<int>vx,vy;
        vx.pb(1),vx.pb(n);
        vy.pb(1),vy.pb(m);
        for(int i=0;i<k;i++)
        {
            int x1=max(1,p[i].x-q);
            int x2=min(n,p[i].x+q);
            vx.pb(x1);
            if(x1-1>1)vx.pb(x1-1);
            if(x2+1<n)vx.pb(x2+1);
    
            int y1=max(1,p[i].y-q);
            int y2=max(m,p[i].y+q);
            vy.pb(y1);
            if(y1-1>1)vy.pb(y1-1);
            if(y2+1<m)vy.pb(y2+1);
        }
        sort(vx.begin(),vx.end());
        vx.resize(unique(vx.begin(),vx.end())-vx.begin());
        sort(vy.begin(),vy.end());
        vy.resize(unique(vy.begin(),vy.end())-vy.begin());
        memset(dp,0,sizeof dp);
        for(int i=0;i<k;i++)
        {
            int x1=max(1,p[i].x-q);
            int x2=min(n,p[i].x+q)+1;
            int y1=max(1,p[i].y-q);
            int y2=min(m,p[i].y+q)+1;
            x1=lower_bound(vx.begin(),vx.end(),x1)-vx.begin()+1;
            x2=lower_bound(vx.begin(),vx.end(),x2)-vx.begin()+1;
            y1=lower_bound(vy.begin(),vy.end(),y1)-vy.begin()+1;
            y2=lower_bound(vy.begin(),vy.end(),y2)-vy.begin()+1;
            dp[x1][y1]++;dp[x2][y2]++;
            dp[x1][y2]--,dp[x2][y1]--;
        }
        int xmax=0,xmin=vx.size()+1,ymax=0,ymin=vy.size()+1;
        for(int i=1;i<=vx.size();i++)
        {
            for(int j=1;j<=vy.size();j++)
            {
                dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
                if(dp[i][j]==0)
                {
                    xmax=max(xmax,i);
                    xmin=min(xmin,i);
                    ymax=max(ymax,j);
                    ymin=min(ymin,j);
                }
            }
        }
        if(xmax==0)return 1;
        int d=max(vx[xmax-1]-vx[xmin-1],vy[ymax-1]-vy[ymin-1]);
        if(d&1)++d;
        d/=2;
        return d<=q;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++)
            scanf("%d%d",&p[i].x,&p[i].y);
    //    printf("%d
    ",ok(3));
        int l=-1,r=max(n,m)+1;
        while(l<r-1)
        {
            int mid=(l+r)>>1;
            if(ok(mid))r=mid;
            else l=mid;
        }
        printf("%d
    ",r);
        return 0;
    }
    /********************
    
    ********************/
    E

    G:题意:有一个无向带权有环图,每两个点之间距离是该路径上的边的权值的异或和,求1到n的最小距离

    题解:这题和bzoj2115很相似,可以用线型基求解,先随便找到一条从1到n的路径,记录异或和,把该路径上的环也记录下来,然后对环的所有权值求线型基,最后贪心的选取线型基来和答案异或取最小值

    那么,为什么随便找一条路径就可以呢,现在假设有另一条路径更优,那么更优路径和选取的路径构成了一个环,那么如果我们选了这个环,那么异或和就变成更优的那个路径,因此答案还是最小的

    线型基在这题中的主要意义是利用最高位的1位置不相同来,使答案中和线型基最高位相同的为1的地方进行异或,这样答案就一定会减小

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    #define y1 y2
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=200000+10,inf=0x3f3f3f3f;
    
    struct edge{
        int to,Next,v;
    }e[N*2];
    int head[N],cnt;
    void add(int u,int v,int c)
    {
        e[cnt].to=v;
        e[cnt].v=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
    }
    bool vis[N];
    int dis[N];
    vector<int>v;
    void dfs(int u)
    {
        vis[u]=1;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(!vis[x])
            {
                dis[x]=dis[u]^e[i].v;
                dfs(x);
            }
            else
            {
                v.pb(dis[x]^dis[u]^e[i].v);
                if(v[v.size()-1]==0)v.pop_back();
            }
        }
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof head);
        cnt=0;
        for(int i=0;i<m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        dfs(1);
    //    for(int i=0;i<v.size();i++)cout<<v[i]<<"++++"<<endl;
    //    cout<<dis[n]<<endl;
        vector<int>base;
        for(int i=0;i<v.size();i++)
        {
            int te=v[i];
            for(int j=0;j<base.size();j++)
                te=min(te,te^base[j]);
            if(te)base.pb(te);
        }
        sort(base.begin(),base.end());
        for(int i=base.size()-1;i>=0;i--)
        {
            int k=0,te=base[i];
            while(te)te/=2,k++;
            k--;
         //   cout<<k<<" "<<base[i]<<" "<<((dis[n]>>k)&1)<<endl;
            if(((dis[n]>>k)&1))dis[n]^=base[i];
        }
        printf("%d
    ",dis[n]);
        return 0;
    }
    /********************
    
    ********************/
  • 相关阅读:
    我的插件架构
    .net 处理图片亮度
    封装自己的对称加密模块
    漏洞无处不在之窃取你的QQ信息
    写自己的自动升级模块
    抓到一只网马,发文顺便鄙视下360
    .net 3.5的Socket异步完成端口
    检测本机是否登录了指定QQ账号
    C++/CLR写的Data Blocks
    修改的Vista风格多功能日历Demo
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8278813.html
Copyright © 2011-2022 走看看