CodeForces 500B - New Year Permutation

原题链接:Problem - 500B - Codeforces

 

 

题目大意:给出一个排列和一个矩阵,排列中不同的两个数可以互换位置,条件是两个位置在矩阵中对应的值为1。通过交换尽可能地使排列升序并输出。

思路:矩阵中为1的值并不代表所有可以交换组合的集合。例如假设1和3位置的数可交换,1和5位置的数也可交换,则3与5位置的数可以通过多次交换得到。从此可联想到floyd算法,对矩阵进行处理得到所有可交换组合的集合。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define TL ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

ll n,a[303];
bool vis[303][303];

void floyd()
{
    for(int k = 1;k <= n;k++)
    {
        for(int i = 1;i <= n;i++)
        {
            for(int j = 1;j <= n;j++)
            {
                vis[i][j] = (vis[k][i]&&vis[k][j]) ? 1 : vis[i][j];
            }
        }
    }
}

int main()
{
    cin >> n;
    for(int i = 1;i <= n;i++) cin >> a[i];
    for(int i = 1;i <= n;i++)
    {
        string s;
        cin >> s;
        for(int j = 1;j <= n;j++)
        {
            vis[i][j] = s[j-1]-'0';
        }
    }
    floyd();
    for(int i = 1;i <= n;i++)
    {
        int k = i,temp = a[i];
        for(int j = i+1;j <= n;j++)
        {
            if(vis[i][j]&&temp>a[j]) temp = a[j],k = j;
        }
        swap(a[k],a[i]);
    }
    for(int i = 1;i <= n;i++)
    {
        cout << a[i] << " ";
    }
    cout << '\n';
    return 0;
}
posted @ 2021-12-22 20:40  wbw1537  阅读(44)  评论(0)    收藏  举报