[1-4] 배열 문제 동전

문제 설명 :
골드 어레이 N '(m £ 100, n은 M 개의 £ 100) 데스크톱 m 행 n 열의 배열에 동전. 각 금
동전 또는 위로 향하거나 백업 할 수 있습니다. 이것은 앞 뒷면까지 금색의 수, 금 0으로 한 상태를 나타낸다.
골드 어레이의 게임의 규칙은 :
(1) 각각은 원래의 위치 위에있는 로우 금 차례로 배치 될 수있다
(2) 임의로 개의 각각이 두 위치 금 전환.
"프로그래밍 작업 :
금 어레이의 초기 및 목표 상태를 설정하는 게임 프로그램의 규칙은 초기 상태에서 금의 배열에 따라 계산된다 금
천이 목표 상태에 필요한 최소 수로 변환 된 상태.
"입력 데이터 :
입력 데이터 파일 input.txt을 주어진다. 데이터 세트 이상의 파일. 첫번째 파일의 양의 정수 k에 1 행은 테이블
도시 된 데이터 세트의 K를 갖는다. 첫 번째 행의 데이터는 각각 두 개의 양의 정수를 m, n은있다. 상기 초기 라인 형 동전 m 배열되는 다음
상태는 제 N 디지털 라인을 갖는 각 행 금의 상태를 나타내고, 전방, 후방 최대 금색 0. 그런 다음,
상기 어레이의 m 행은 타겟 상태 금이다.
'출력 결과
횟수 입력 데이터의 경우 output.txt 순서대로 출력 파일에 계산 된 최소의 전환. 경우에는 용액 대응하는 데이터
를 출력하지 -1.
입력 샘플, 출력 샘플 파일
OUTPUT.TXT input.txt를
2
. 4. 3
. 1 1 0
0 0 0
. 1 0.1
. 0 1 1
1 0 1
1 1 1
0 1 1
1 0 1
4 3
1 0 1
0 0 0
1 0 0
1 1 1
1 1 0
1 1 1
0 1 1
1 0 1
2
-1

[설명]


우리는 어레이 및 어레이 B의 j 번째 열의 첫 번째 열에서 최종 응답이 동일하다고 가정
하고 있으므로 먼저 라인 동작이 정말로 배열 및 B에 j 번째 열의 배열 넣어 부정 할 첫 번째 행 같은.
이번에는 당신이 더 이상 라인 작업을 깨뜨릴 수 없다는 것을 발견 할 것이다.
만 다음 교환 작업을 할 수 있습니다.
그런 다음 (문자열로 표시) 배열 및 B n 개의 열 벡터의 배열에 넣고, 어레이의 2 열의 시퀀스 (문자열 사전 식 순서) 같은 문자열에 따른다.
만약 두 개의 스트링 어레이 동일하게, 다음은 A에서 B로 변경 될 수
난 그것에 레코드의 첫 번째 열을 변경할 B 열에 토륨.
: 그럼 다른 문제가된다
다음 I [I] 위치에 마지막으로 알려진 위치에 번호. 교환 연산은 모두 충족하기 위해 여러 사이클의 최소 요청할 수 I (1 <= I는 = < N)
[시그마 (-1의 고리 크기) 절차 결국 복수의 링을 형성하는 고전적인 문제이며 부정 조작 전에 여러번 동일한 상황 j 번째 열 및 첫 번째 열에 응답 (B)에 연결되고

[코드]

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

struct abc{
    string s;
    int column;
};

const int N = 100;

int T,m,n;
int a[N+10][N+10],b[N+10][N+10];
abc bcs[N+10];
int aa[N+10][N+10];
int minstep = -1;

bool cmp(abc a,abc b){
    return a.s<b.s;
}

void fz(int r){
    for (int i = 1;i <= n;i++){
        aa[r][i] = 1-aa[r][i];
    }
}



int judge(int idx){

    int step = 0;
    for (int i = 1;i <= m;i++){
        if (aa[i][idx]!=b[i][1]){
            fz(i);
            step++;
        }
    }
    //把aa的每一列看成一个长度为m的01字符串,即n个字符串
    abc acs[N+10];
    int nex[N+10];//记录aa的每一列需要变换到哪一列
    for (int j = 1;j <= n;j++){
        string temp = "";
        for (int i = 1;i <= m;i++){
            temp = temp + (char)(aa[i][j]+'0');
        }
        acs[j].column = j;
        acs[j].s = temp;
    }
    sort(acs+1,acs+1+n,cmp);
    //for (int i = 1;i <= n;i++) cout<<acs[i].s<<" ";cout<<endl;
    //for (int i = 1;i <= n;i++) cout<<bcs[i].s<<" ";
    //exit(0);
    for (int i = 1;i <= n;i++)
        if (acs[i].s!=bcs[i].s)
            return -1;
        else {
            nex[acs[i].column] = bcs[i].column;
        }
    int flag[N+10];
    for (int i = 1;i <= n;i++) flag[i] = -1;
    for (int i = 1;i <= n;i++)
        if (flag[i]==-1){
            int j = i;
            int cnt = 0;
            while (flag[j]==-1){
                flag[j] = 1;
                cnt++;
                j = nex[j];
            }
            step+=cnt-1;
        }
    return step;
}

int main(){
    //freopen("E://tran5.in","r",stdin);
    cin >> T;
    while (T--){
        minstep = -1;
        cin >> m >> n;
        for(int i = 1;i <= m;i++)
            for (int j = 1;j <= n;j++)
                cin >> a[i][j];
        for(int i = 1;i <= m;i++)
            for (int j = 1;j <= n;j++)
                cin >> b[i][j];
        //将b转换成n个列向量
        for (int j = 1;j <= n;j++){
            string temp="";
            for (int i = 1;i <= m;i++){
                temp = temp + (char)(b[i][j]+'0');
            }
            bcs[j].s = temp;
            bcs[j].column = j;
        }
        sort(bcs+1,bcs+1+n,cmp);

        for (int j = 1;j <= n;j++){//suppose j column equal to first column of b
            memcpy(aa,a,sizeof(a));
            int t = judge(j);
            if (t==-1) continue;
            if (minstep==-1){
                minstep = t;
            }else minstep = min(minstep,t);
        }
        cout<<minstep<<endl;
    }
    return 0;
}

추천

출처www.cnblogs.com/AWCXV/p/11616757.html