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;
}
原文地址:https://www.cnblogs.com/tiny656/p/2864087.html