zoukankan      html  css  js  c++  java
  • Codeforces Round #161 (Div. 2)

    A.Beautiful Matrix  

    如果1的位置在Matrix中为x,y(从1开始计数),答案为abs(3-x)+abs(3-y)

    B.Squares  

    满足所选的点要包含在对角点(0,0)到(ai,ai)这样的刚好k个正方形内(边界也算),降序sort一遍a数组,输出(a[k-1],a[k-1])或者(a[k-1],0)什么的都行

    C.Circle of Numbers    

    构造出满足题意的序列就可以,因为不限制排列开始的元素位置,不限制顺时或是逆时,所以直接可以让1是第一个元素,tutorial里的方法是分情况判断构造出第二三个元素,然后依约束的关系去恢复剩下的元素。刚开始要去判断每个元素是否仅仅出现的4次,否则-1.

    这里我用的dfs+回溯的方法来做,虽然元素很多,但是每个元素相连接的点只有4个,还比较快。

    用vis数组标记使用过的元素

    对于Ans中只有1个元素时候,第2个元素需要满足,link[1]中包含元素2,搜的时候就是按照邻接关系来搜的,这是必然的。

    对于Ans中多于1个元素的时候,每添加一个新元素,如 A B C(Prepare to add),需要约束条件link[A]中包含A、C,link[B]中包含C.

    不断的搜索直到Ans的大小为n时,答案就有了。

    但是某些组合满足每个元素都出现4次,但是也可能构造不出圈,所以我对于那些没有printf出答案然后exit(0)的数据,后面补一个-1.

    View Code
    vector<int> link[100005];
    int cnt[100005];
    int vis[100005];
    vector<int> ans;
    int n;
    
    int has(vector<int> e, int val)
    {
        for(int i = 0; i < e.size(); i++)
            if(e[i] == val)    return 1;
        return false;
    
    }
    
    void dfs(int val)
    {
        int i;
        vis[val] = 1;
        ans.push_back(val);
    //     for(i = 0;i < ans.size(); i++)
    //         printf("%d ", ans[i]);
    //     printf("\n");
        if(ans.size() == n)    
        {
            for(i = 0;i < n; i++)
                printf("%d ", ans[i]);
            printf("\n");
            exit(0);
        }
        
        for(i = 0; i < link[val].size(); i++)
        {
            if(!vis[ link[val][i] ] && ans.size() <= 1)
            {
                dfs( link[val][i] );
                vis[ link[val][i] ] = 0;
                ans.pop_back();
            }
            else if(!vis[ link[val][i] ] && ans.size() >= 2)
            {
                if(has( link[ ans[ ans.size()-2 ] ], ans[ ans.size()-1 ] ) && has(link[ ans[ans.size()-2] ], link[val][i]) 
                    &&    has( link[ ans[ ans.size()-1 ] ], link[val][i]) )
                {
                    dfs( link[val][i] );
                    vis[ link[val][i] ] = 0;
                    ans.pop_back();
                }
            }
        }
    }
    
    int main()
    {
        int a,b,i;
        get(n);
        memset(cnt,0,sizeof(cnt));
        memset(vis,0,sizeof(vis));
        for(i = 0; i < 2*n; i++)
        {
            get(a);get(b);
            cnt[a]++; cnt[b]++;
            link[a].push_back(b);
            link[b].push_back(a);
        }
        int ok = 1;
        for(i = 1; i <= n; i++)
        {
            if(cnt[i] != 4)
            {
                ok = 0;
                break;
            }
        }
        if(!ok)    printf("-1\n");
        else
        {
            dfs(1);
            printf("-1\n");
        }
        return 0;
    }

    D.Cycle in Graph  

    给一个无向图,求某个输出某个环,长度 ≥ k+1.

    如果存在一条路径v1,v2,...,vr,若vr的相邻点中包括v1,那么就至少形成了一个长度为r的环,只要r ≥ k+1满足题意输出答案就可以了。

    用DFS+回溯的方法去搜索这样可能的路径。

    View Code
    /*
    DFS+回溯,找出大于等于k+1的环。
    */
    
    vector< int > adj[100005];
    vector< int > path;
    int vis[100005];
    int k;
    
    void dfs(int cur,int len)
    {
        int i,j;
        path.push_back(cur);
        vis[cur] = 1;
        len++;
        if(len >= k+1)
        {
            for(i = 0; i < adj[cur].size(); i++)    
            {
                if(adj[cur][i] == path[0])
                {
                    printf("%d\n", len);
                    for(j = 0; j < path.size(); j++)
                        printf("%d ", path[j]);
                    printf("\n");
                    exit(0);
                }
            }
        }
        for(i = 0; i < adj[cur].size(); i++)
        {
            if(!vis[adj[cur][i]])    dfs(adj[cur][i],len);
        }
        vis[cur] = 0;
        path.pop_back();
    }
    
    int main()
    {
        int a,b,i,m,n;
        get(n);get(m);get(k);
        memset(vis,0,sizeof(vis));
        for(i = 1; i <= m; i++)
        {
            get(a);get(b);
            adj[a].push_back(b);
            adj[b].push_back(a);
        }
        for(i = 1; i <= n; i++)
            dfs(i,0);
        return 0;
    }

    E.Rhombus

    解题的方法,就和题目意思一样,从菱形的角度来考虑。

      ≥ 0, 而是坐标(i, j)到坐标(x, y)的曼哈顿距离,约束出来是一个菱形。

    当k = 2时候,这个式子在(x,y)处表达的图案如下

    在该点处f(x,y) = 2*ax,y + 1*(ax-1,y-1 + ax+1,y-1 + ax-1,y+1 + ax+1,y+1) , 所以依次类推。

    把菱形按照距离相关的权值,从大到小把菱形分圈,每个权值圈,找出它的ai,j的总和,然后在和权值运算。

    可以数组记录,斜左下,斜右下的递增和,这样求菱形每一遍和时候,每一段只用O(1)就可以求出。

    最后brute force,遍历能取的所有位置,记录最大值出现位置。

    搓方法,O(n3),2781ms跑完所有数据,接近超时了。Tutorial 方法更好一些。

    View Code
    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <iomanip>
    #include <vector>
    #include <deque>
    #include <list>
    #include <set>
    #include <map>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <string>
    #include <numeric>
    #include <functional>
    #include <iterator>
    #include <typeinfo>
    #include <utility>
    #include <memory>
    #include <cmath>
    #include <cstdlib>
    #include <cctype>
    #include <cstddef>
    #include <complex>
    #include <ctime>
    #include <cassert>
    using namespace std;
    
    typedef __int64 LL;
    static inline bool get(int &v)
    {
        int s = 1, c;
        while(!isdigit(c = getchar())&&c != '-')
        {
            if(c == EOF)
                break ;
        }
        if(c == EOF) return 0;
        if(c == '-') s = 0 , v = 0;
        else v = c^48;
        for(;isdigit(c = getchar());v = (v << 1) + (v << 3) + (c ^ 48));
        v = (s ? v : -v);
        return 1 ;
    }
    
    struct st
    {
        int val;
        LL l;
        LL r;
    }matrix[1005][1005];
    
    void init(int n,int m)
    {
        int i, j;
        for(i = 0; i <= n; i++)
        {
            for(j = 0; j <= m+1; j++)
            {
                matrix[i][j].val = 0;
                matrix[i][j].l = 0;
                matrix[i][j].r = 0;
            }
        }
    }
    
    int main()
    {
        int n,m,k,i,j,v,a,b;
        get(n);get(m);get(k);
        init(n,m);
        for(i = 1; i <=  n; i++)
        {
            for(j = 1; j <= m; j++)
            {
                get(matrix[i][j].val);
                matrix[i][j].l = matrix[i-1][j+1].l + matrix[i][j].val;
                matrix[i][j].r = matrix[i-1][j-1].r + matrix[i][j].val;
            }
        }
        LL ans = 0;
        a = k;
        b = k;
        for(i = k; i <= n-k+1; i++)
            for(j = k; j <= m-k+1; j++)
            {
                LL res = 0;
                for(v = k; v >= 1; v--)
                {
                    if(v == k)
                    {
                        res += k*matrix[i][j].val;
                    }
                    else
                    {
                        LL tmp = 0;
                        tmp += matrix[i][j-(k-v)].l - matrix[i-(k-v)][j].l;
                        tmp += matrix[i+(k-v)][j].l - matrix[i][j+(k-v)].l;
                        tmp += matrix[i+(k-v)][j].r - matrix[i][j-(k-v)].r;
                        tmp += matrix[i][j+(k-v)].r - matrix[i-(k-v)][j].r;
                        tmp += matrix[i-(k-v)][j].val;
                        tmp -= matrix[i+(k-v)][j].val;
                        res += v*tmp;
                    }
                }
                //printf("%d\n" ,res);
                if(res > ans)
                {
                    ans = res;
                    a = i;
                    b = j;
                }
            }
            printf("%d %d\n", a,b);
            return 0;
    }
  • 相关阅读:
    JavaScript
    94.Binary Tree Inorder Traversal
    144.Binary Tree Preorder Traversal
    106.Construct Binary Tree from Inorder and Postorder Traversal
    105.Construct Binary Tree from Preorder and Inorder Traversal
    90.Subsets II
    78.Subsets
    83.Merge Sorted Array
    80.Remove Duplicates from Sorted Array II
    79.Word Search
  • 原文地址:https://www.cnblogs.com/tiny656/p/2864087.html
Copyright © 2011-2022 走看看