zoukankan      html  css  js  c++  java
  • 2017-2018 ACM-ICPC NEERC Southern Subregional Contest(3)

    *A. Automatic Door

    题意

    分析


    *C

    题意

    分析


    *G

    题意

     

    分析

     


    E.Field of Wonders

    签到


    F. Lost in Transliteration

    签到


    M. Quadcopter Competition

    签到


    H. Palindromic Cut

    题意

    给一个长度为n的字符串,尽可能的少的分成长度相同的回文串,输出回文串个数,以及每个回文串


     分析

    考虑回文串,直接将字符分成两类,能回文的长度为2的串(eg:aa),长度为1的串(eg:a),然后暴力分别算出数量令前者sum1,后者sum2,暴力找到sum1%sum2==0的情况(2可以分成两个1),然后输出即可 

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<queue>
    #include<time.h>
    #define ll long long
    using namespace std;
    #define mp make_pair
    #define pb push_back
    #define lson l,mid,pos<<1
    #define rson mid+1,r,pos<<1|1
    const double PI=acos(-1);
    const int maxm=2000+5;
    //const int maxn=1e5+5;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    //int dir[4][2]={0,1,1,0,0,-1,-1,0};
    //ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    //ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    //ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
    //ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
    
    
    vector<char> odd,even;
    int n,cnt[300];
    char str[400010], ans[400010];
    int main()
    {
        scanf("%d",&n);
        scanf("%s",str+1);
        for (int i=1;i<=n;i++)
            cnt[str[i]]++;
        for (int i=0;i<=256;i++)
            if (cnt[i])
            {
                if (cnt[i]&1)
                {
                    cnt[i]--;
                    odd.push_back(i);
                }
                for (int j=1;j<=cnt[i]/2;j++)
                    even.push_back(i);
            }
        if (odd.size()==0)
        {
            for (int i=1;i<=n/2;i++)
                ans[i]=ans[n-i+1]=even[i-1];
            printf("1
    ");
            for (int i=1;i<=n;i++)
                printf("%c",ans[i]);
            return 0;
        }
        else
        {
            while (even.size()%odd.size())
            {
                odd.push_back(even.back());
                odd.push_back(even.back());
                even.pop_back();
            }
            printf("%d
    ",(int)odd.size());
            for (int i=1;i<=(int)odd.size();i++)
            {
                ans[(n/odd.size())/2]=odd[i-1];
                for (int j=1;j<=n/odd.size()/2;j++)
                    ans[(n/odd.size()/2)-j]=ans[(n/odd.size()/2)+j]=even.back(),even.pop_back();
                for (int j=0;j<n/odd.size();j++) printf("%c",ans[j]);
                printf(" ");
            }
        }
        return 0;
    }
    View Code

    *I. Photo Processing

    题意

    给n个数分组,每组至少分k个数(不要求连续分),每组的mex值为每组的max-min,这n个数的mex为所有组mex的max,使这个max最小,并求出这个数


    分析

    很容易下想到,二分答案,check(mid)用dp,dp[i]表示1~i可以分组的最远位置

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<queue>
    #include<time.h>
    #include<unordered_map>
    #include<unordered_set>
    #define ll long long
    using namespace std;
    #define mp make_pair
    #define pb push_back
    #define lson l,mid,pos<<1
    #define rson mid+1,r,pos<<1|1
    const double PI=acos(-1);
    const int maxm=2000+5;
    const int maxn=3e5+5;
    const int mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    //int dir[4][2]={0,1,1,0,0,-1,-1,0};
    //ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    //ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    //ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
    //ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
    
    int n, k;
    int a[maxn];
    int dp[maxn];
    
    bool check(int answer)
    {
         int id = 0;
         for(int i = k; i <= n; i++)
         {
             int point = dp[i-k];
             if((a[i]-a[dp[i-k]+1]) <= answer) id = i;
             dp[i] = id;
         }
         if(dp[n] == n)
            return true;
         else
            return false;
    }
    
    int  main()
    {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n;i++)
        {
    
            scanf("%d", &a[i]);
        }
        sort(a+1,a+n+1);
        int l = 0, r = 1000000000;
        while(l < r)
        {
            int mid = (l+r)/2;
            if(check(mid))
            {
                r = mid;
            }
            else
            {
                l = mid+1;
            }
        }
        printf("%d
    ", l);
        return 0;
    }
    View Code

    K. Road Widening

    题意

    给n条路,每条路都有一个初始的宽度和一个最多可以加的宽度,现要求每条路的最终宽度S[i],满足 |s'i + 1 - s'i| ≤ 1  (1 <= i < n)都成立,问所有路最多能加多少(和)以及每条路最终的宽度, 没有满足条件的解输出-1


    分析

    分析可得这道题和两个区间的关系有一定联系(六种情况)?

    首先可以否定的是从前往后或者从后往前尽可能多的取,因为可能不满足题意,其实很直观的是维护每个点的合法区间(通过上下两个区间关系,画出两个区间观察就可以看出来),下面就是如何维护合法区间,从前往后扫一边维护每一个点的合法区间的左右端点,从前往后扫的时候 i 和 i-1形成了一个制约关系, 不难理解一个位置i的值得确定和左右两边的数都有关系,所以在从后往前扫一遍求出每个位置具体的值即可

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2e5 + 5;
    
    int n;
    int a[maxn], g[maxn], xmax[maxn], xmin[maxn];
    int now[maxn];
    
    int main()
    {
        scanf("%d", &n);
        long long sum = 0, ans = 0;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d%d", &a[i], &g[i]);
            g[i] = a[i]+g[i];
        }
        xmax[1] = g[1];
        xmin[1] = a[1];
        for(int i = 2; i <= n; i++)
        {
            xmax[i] = min(g[i], xmax[i-1]+1);
            xmin[i] = max(a[i], xmin[i-1]-1);
            if(xmax[i] < xmin[i])
            {
                printf("-1
    ");
                return 0;
            }
        }
        sum += xmax[n] - a[n];
        ans = xmax[n];
        now[n] = xmax[n];
        for(int i = n-1; i >= 1; i--)
        {
            if(ans+1 <= xmax[i])
              ans = ans+1;
            else if(ans<=xmax[i])
              ans =ans;
              else
                ans = ans -1;
             now[i]=ans;
            sum += ans-a[i];
    
        }
        printf("%I64d
    ", sum);
        for(int i = 1; i <= n; i++)
        printf("%d%c", now[i],i==n?'
    ':' ');
        return 0;
    }
    View Code
    要么优秀要么生锈
  • 相关阅读:
    form表单中有bootstrap-switch时怎么提交表单
    Django:drf过滤、搜索、排序功能
    pycharm:使用豆瓣源安装第三方库
    pycharm安装包时:Non-zero exit code (1)
    js: 前端通过ajax方式获取后台数据填充下拉列表
    Django:drf框架中序列化组件—字段验证
    ROS Reality: A Virtual Reality Framework Using Consumer-Grade Hardware for ROS-Enabled Robots David
    Virtual and Augmented Reality for Robotics in Unity environment using Mimic plugin
    Human-machine collaboration in virtual reality for adaptive production engineering
    An open modular framework for efficient and interactive simulation and analysis of realistic human motions for professional applications
  • 原文地址:https://www.cnblogs.com/Superwalker/p/7845685.html
Copyright © 2011-2022 走看看