Codeforces Round #290 (Div. 2) A,B,C,D

畫船聽雨發表於2015-02-03

這場CF終於當了一次手速狗啊,簡直了啊。

A:簽到,輸出一個蛇形,看著樣例找到規律列印路徑就可以了。

int main()
{
    int n, m;
    while(cin >>n>>m)
    {
        for(int i = 1; i <= n; i++)
        {
            if(i%2)
            {
                for(int j = 0; j < m; j++)
                    cout<<"#";
                cout<<endl;
            }
            else
            {
                int xp = i/2;
                if(xp%2)
                {
                    for(int j = 0; j < m-1; j++)
                         cout<<".";
                    cout<<"#"<<endl;
                }
                else
                {
                    cout<<"#";
                    for(int j = 0; j < m-1; j++)
                        cout<<".";
                    cout<<endl;
                }
            }
        }
    }
}
B.預處理出來所有點之間的關係然後用dfs判斷是否構成環,保證每個點只被搜一次,所以時間複雜度不是很高。

const int maxn = 110;

char str[maxn][maxn];
vector<int>g[maxn*maxn];

int vis[maxn*maxn];

int dx[] = {0, 1, -1, 0};
int dy[] = {1, 0, 0, -1};

int flag;

void dfs(int x, int fa)
{
    int n = g[x].size();
    vis[x] = 1;
    for(int i = 0; i < n; i++)
    {
        int xp = g[x][i];
        if(xp == fa) continue;
        if(vis[xp])
        {
            flag = 1;
            continue;
        }
        else
        {
            dfs(xp, x);
        }
    }
}

int main()
{
    int n, m;
    while(cin >>n>>m)
    {
       for(int i = 1; i <= n; i++)
        scanf("%s",str[i]+1);
        for(int i = 0; i <= n*m; i++)
            g[i].clear();
       for(int i = 1; i <= n; i++)
       {
           for(int j = 1; j <= m; j++)
           {
               int pos = (i-1)*m+j;
               for(int k = 0; k < 4; k++)
               {
                   int x = i+dx[k];
                   int y = j+dy[k];
                   if(x > n || x < 1 || y > m || y < 1) continue;
                   int xpos = (x-1)*m+y;
                   if(str[i][j] == str[x][y])
                   {
                       g[pos].push_back(xpos);
                   }
               }
           }
       }

       memset(vis, 0, sizeof(vis));
       flag = 0;
       for(int i = 1; i <= n*m; i++)
       {
           if(!vis[i])
           {
               dfs(i, -1);
           }
       }
       if(flag) cout<<"Yes"<<endl;
       else cout<<"No"<<endl;
    }
}

C.標準的拓撲排序,建立出來拓撲關係之後,拓撲排序如果有環就說明不可以。好多人多沒有判斷

2

aa

a

 這種情況,沒去hack有點失誤。

using namespace std;

const int maxn = 110;

char str[maxn][maxn];

int mp[maxn][maxn];
int in[maxn];
int num[maxn];
int f[maxn];
int main()
{
    int n;
    while(cin >>n)
    {
        for(int i = 0; i < n; i++)
        {
            scanf("%s",str[i]);
        }
        for(int i = 0; i < n; i++)
        {
            num[i] = strlen(str[i]);
        }
        memset(mp, 0, sizeof(mp));
        memset(in, 0, sizeof(in));
        int xflag = 0;
        for(int i = 0; i < n-1; i++)
        {
            int m = min(num[i], num[i+1]);
            int xnum = 0;
            for(int j = 0; j < m; j++)
            {
                if(str[i][j] != str[i+1][j])
                {
                    int x = str[i][j]-'a';
                    int y = str[i+1][j]-'a';
                    if(mp[x][y] == 0)
                    {
                        mp[x][y] = 1;
                        in[y]++;
                    }
                    break;
                }
                xnum++;
            }
            if(xnum == m)
            {
                if(num[i] > num[i+1])
                {
                    xflag = 1;
                }
            }
        }
        if(xflag)
        {
            puts("Impossible");
            continue;
        }
        int num = 0;
        int t;
        while(num != 26)
        {
            int flag = 0;
            for(int i = 0; i < 26; i++)
            {
                if(in[i] == 0)
                {
                    flag = 1;
                    in[i] = -1;
                    f[num++] = i;
                    t = i;
                    break;
                }
            }
            if(!flag) break;
            for(int i = 0; i < 26; i++)
            {
                if(mp[t][i] == 1)
                {
                    in[i]--;
                }
            }
        }
        if(num != 26)
        {
            cout<<"Impossible"<<endl;
            continue;
        }
        for(int i = 0; i < 26; i++)
            printf("%c",'a'+f[i]);
        cout<<endl;
    }
}

D.思路出了問題,應該是找到一些數使得他們的最大公約數為1,這樣一定會到達所有的點,類似於ax+by = 1,找出來最小的解是的滿足最大公約數為1,且花費最小。可以用map來存這樣就解決了,開靜態記憶體太大的問題,當然也可以離散來存資料。

const int maxn = 30010;

using namespace std;

int main()
{
    int n;
    while(cin >>n)
    {
        vector<int>f;
        vector<int>p;
        int x;
        for(int i = 0; i < n; i++)
        {
            cin >>x;
            f.push_back(x);
        }
        for(int i = 0; i < n; i++)
        {
            cin >>x;
            p.push_back(x);
        }
        map<int, int> mp;
        map<int, int>::iterator it;
        for(int i = 0; i < n; i++)
        {
            int &x = mp[f[i]];
            if(x == 0) x = p[i];
            else x = min(p[i], x);
            for(it = mp.begin(); it != mp.end(); it++)
            {
                int &y = mp[__gcd(f[i], it->first)];
                if(y == 0) y = p[i]+it->second;
                else y = min(y, p[i]+it->second);
            }
        }
        if(mp[1])
        {
            cout<<mp[1]<<endl;
            continue;
        }
        puts("-1");
    }
}



相關文章