zoukankan      html  css  js  c++  java
  • Codeforces Round #542题解

    A题

    如果是0大于一半,无解,否则取多的一边即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int a[N];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        int i;
        cin>>n;
        for(i=1;i<=n;i++)
            cin>>a[i];
        int cnt1=0,cnt2=0;
        for(i=1;i<=n;i++){
            if(a[i]<0)
                cnt1++;
            if(a[i]>0)
                cnt2++;
        }
        n=(n+1)/2;
        if(cnt1<n&&cnt2<n){
            cout<<0<<endl;
        }
        else{
            if(cnt1<n){
                cout<<1<<endl;
            }
            else{
                cout<<-1<<endl;
            }
        }
        return 0;
    }
    View Code

    B题

    你会发现,因为必须要按照顺序走,因此肯定是先走到两个1,再走到两个2,这样整体的变化其实就是两种情况a[i-1][1]->a[i][1],a[i-1][2]->a[i][2],或者a[i-1][2]->a[i][1],a[i-1][1]->a[i][2]

    对于两种取min即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int a[N];
    int vis[N];
    int pos[N][2];
    int main(){
        ios::sync_with_stdio(false);
        int n;
        cin>>n;
        n*=2;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
            if(pos[a[i]][1]){
                pos[a[i]][2]=i;
            }
            else{
                pos[a[i]][1]=i;
            }
        }
        ll ans=pos[1][1]-1+pos[1][2]-1;
        for(i=2;i<=n/2;i++){
            ans+=min(abs(pos[i][1]-pos[i-1][1])+abs(pos[i][2]-pos[i-1][2]),abs(pos[i][1]-pos[i-1][2])+abs(pos[i][2]-pos[i-1][1]));
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    C题

    显然划分连通块,如果在同一个连通块里面说明为0,不然根据直线最短距离,我们枚举两个连通块里的点计算最小值

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int sx,sy,tx,ty;
    int s[1010][1010];
    vector<pll> g[N];
    int vis[100][100];
    int cnt=0;
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    int n;
    map<pll,int> m1;
    void dfs(int a,int b){
        int i;
        vis[a][b]=1;
        g[cnt].push_back({a,b});
        m1[{a,b}]=cnt;
        for(i=0;i<4;i++){
            int x=a+dx[i];
            int y=b+dy[i];
            if(x>=1&&x<=n&&y>=1&&y<=n){
                if(!vis[x][y]&&(s[x][y]==0)){
                    dfs(x,y);
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        int i,j;
        cin>>n;
        cin>>sx>>sy>>tx>>ty;
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                char c;
                cin>>c;
                if(c=='0')
                    s[i][j]=0;
                else
                    s[i][j]=1;
            }
        }
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                if(s[i][j]==0&&!vis[i][j]){
                    cnt++;
                    dfs(i,j);
                }
            }
        }
        if(m1[{sx,sy}]==m1[{tx,ty}]){
            cout<<0<<endl;
        }
        else{
            int ans=1e9;
            for(auto x:g[m1[{sx,sy}]]){
                for(auto y:g[m1[{tx,ty}]]){
                    int d=(x.first-y.first)*(x.first-y.first)+(x.second-y.second)*(x.second-y.second);
                    ans=min(ans,d);
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    D1题

    先做的D1题,观察到数据范围很小,直接暴力模拟就能通过,这里的想法是因为每个点只能上一个,并且都要绕一圈才能上第二个,所以每个位置独立,并按照离当前位置远近贪心排序

    D1用的是vector直接模拟

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int a[N],b[N];
    vector<int> num;
    vector<pll> g[N];
    vector<pll> tmp[N];
    int vis[1010];
    bool cmp(pll a,pll b){
        return a.second>b.second;
    }
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int i,j;
        for(i=1;i<=m;i++){
            cin>>a[i]>>b[i];
            int x=b[i]-a[i];
            if(x<0)
                x+=n;
            g[a[i]].push_back({b[i],x});
        }
        for(i=1;i<=n;i++){
            sort(g[i].begin(),g[i].end(),cmp);
        }
        for(int i=1;i<=n;i++){
            int pos=i;
            int cnt=0;
            int ans=0;
            num.clear();
            for(j=1;j<=n;j++)
                tmp[j]=g[j];
            while(1){
                if(tmp[pos].size()){
                    num.push_back(tmp[pos][0].first);
                    tmp[pos].erase(tmp[pos].begin());
                }
                for(int i=0;i<(int)num.size();i++){
                    int x=num[i];
                    if(x==pos){
                        cnt++;
                    }
                }
                vector<int> dd;
                dd.clear();
                for(auto x:num){
                    if(x!=pos)
                        dd.push_back(x);
                }
                num=dd;
                if(cnt==m){
                    cout<<ans<<" ";
                    break;
                }
                pos++;
                ans++;
                if(pos>n)
                    pos-=n;
            }
        }
        return 0;
    }
    View Code

    D2题 

    原理与上题相同,因为不能无脑模拟,再仔细想一想性质发现其实只有每个位置的最后一个点有用

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int a[N],b[N];
    vector<int> num;
    vector<pll> g[N];
    vector<pll> tmp[N];
    int vis[1010];
    bool cmp(pll a,pll b){
        return a.second>b.second;
    }
    int main(){
        ios::sync_with_stdio(false);
        int n,m;
        cin>>n>>m;
        int i,j;
        for(i=1;i<=m;i++){
            cin>>a[i]>>b[i];
            int x=b[i]-a[i];
            if(x<0)
                x+=n;
            g[a[i]].push_back({b[i],x});
        }
        for(i=1;i<=n;i++){
            sort(g[i].begin(),g[i].end(),cmp);
        }
        for(int i=1;i<=n;i++){
            int ans=0;
            for(j=1;j<=n;j++){
                if((int)g[j].size()==0)
                    continue;
                int op=j-i;
                if(op<0)
                    op+=n;
                int cnt=op;
                cnt+=((int)g[j].size()-1)*n;
                int x=g[j][(int)g[j].size()-1].first-j;
                if(x<0)
                    x+=n;
                cnt+=x;
                ans=max(ans,cnt);
            }
            cout<<ans<<" ";
        }
        cout<<endl;
        return 0;
    }
    View Code

    E题

    对于构造合法方案题,我认为一定要从边界构造开始,也就是情况越简单越好,这样讨论就不会很复杂,那么其实我们当作2000个点,只要最后两个点有值并按照模数计算一下

    就能获取正确答案,做构造题的时候,极端条件或者题目通性感觉比较好做一点

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=5e5+10;
    int main(){
        ios::sync_with_stdio(false);
        int k,a;
        cin>>k;
        a=2000-k%2000+998000;
        cout<<2000<<endl;
        int i;
        for(i=1;i<=1998;i++){
            cout<<0<<" ";
        }
        cout<<-a+(k+a)/2000<<" "<<a<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    收藏的一些前端学习的网址
    使用box-shadow 实现水波、音波的效果
    asyncjs,waterfall的使用
    兼容opacity的方法
    在php框架中写正规则表达式时的磕绊
    浏览器的渲染原理
    正规则表达式判断数字
    ie6,7,8不兼容rgba,写background时候不要写成rgba
    jquery-ias插件详解
    制作手机页面过程中遇到的一点问题
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14157329.html
Copyright © 2011-2022 走看看