Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

โปรแกรม C++ หาจำนวนเมทริกซ์ที่ไม่ซ้ำกันซึ่งสร้างได้จากการสลับแถวและคอลัมน์


สมมติว่าเรามีเมทริกซ์ขนาด n x n แต่ละองค์ประกอบในเมทริกซ์มีค่าไม่ซ้ำกันและเป็นจำนวนเต็มระหว่าง 1 ถึง n2 ตอนนี้เราสามารถดำเนินการต่อไปนี้ในปริมาณและลำดับใดก็ได้

  • เราเลือกจำนวนเต็ม x และ y ใดๆ ที่อยู่ในเมทริกซ์ โดยที่ (1 ≤ x < y ≤ n) และสลับคอลัมน์ที่มี x และ y

  • เราเลือกจำนวนเต็ม x และ y ใดๆ ที่อยู่ในเมทริกซ์ โดยที่ (1 ≤ x < y ≤ n) และสลับแถวที่มี x และ y

  • เราต้องทราบว่า x + y ≤ k และค่าเหล่านี้ต้องไม่อยู่ในแถวและคอลัมน์เดียวกัน

เราต้องหาจำนวนเมทริกซ์ที่ไม่ซ้ำกันซึ่งได้มาจากการดำเนินการดังกล่าว

ดังนั้น หากอินพุตเป็น n = 3, k = 15, mat = {{4, 3, 6}, {5, 9, 7}, {1, 2, 8}} ผลลัพธ์จะเป็น 36

ตัวอย่างเช่น ค่าที่เลือกคือ x = 3 และ y = 5 เมทริกซ์ที่ได้หากสลับคอลัมน์จะเป็น -

3 4 6 9 5 7 2 1 8

สามารถได้เมทริกซ์ที่ไม่ซ้ำกัน 36 เมทริกซ์ด้วยวิธีนี้

เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนต่อไปนี้ -

กำหนดฟังก์ชัน dfs() ซึ่งรับ k, อาร์เรย์ ver และ visited, สแต็ก s
  ถ้า visited[k] ไม่เป็นศูนย์ แล้ว:
    return
  visited[k] := true
  ใส่ k ลงใน s
  สำหรับตัววนซ้ำ j := เริ่มต้นของ ver[k], เมื่อ j ไม่เท่ากับองค์ประกอบสุดท้ายของ ver[k], เพิ่ม j ขึ้นทีละ 1, ทำ:
    dfs(*j, ver, visited, s)
กำหนดอาร์เรย์ f ขนาด: 51. f[0] := 1
สำหรับ i := 1, เมื่อ i <= 50, เพิ่ม i ขึ้นทีละ 1, ทำ:
  f[i] := (i * f[i - 1]) mod modval
กำหนดอาร์เรย์ e ขนาด n
กำหนดอาร์เรย์ pk ขนาด n
สำหรับ i := 0, เมื่อ i < n, เพิ่ม i ขึ้นทีละ 1, ทำ:
  สำหรับ j := i + 1, เมื่อ j < n, เพิ่ม j ขึ้นทีละ 1, ทำ:
    chk := 0
    สำหรับ l := 0, เมื่อ l < n, เพิ่ม l ขึ้นทีละ 1, ทำ:
      ถ้า (mat[i, l] + mat[j, l]) > k, แล้ว:
        chk := 1
        ออกจากลูป
    ถ้า chk เท่ากับ 0, แล้ว:
      ใส่ j ที่ท้ายของ pk[i]
      ใส่ i ที่ท้ายของ pk[j]
    chk := 0
    สำหรับ l := 0, เมื่อ l < n, เพิ่ม l ขึ้นทีละ 1, ทำ:
      ถ้า (mat[l, i] + mat[l, j]) > k, แล้ว:
        chk := 1
        ออกจากลูป
      ถ้า chk เท่ากับ 0, แล้ว:
        ใส่ j ที่ท้ายของ e[i]
        ใส่ i ที่ท้ายของ e[j]
resa := 1, resb = 1
กำหนดอาร์เรย์ v1 ขนาด: n และ v2 ขนาด: n.
สำหรับ i := 0, เมื่อ i < n, เพิ่ม i ขึ้นทีละ 1, ทำ:
  v1[i] := false
  v2[i] := false
สำหรับ i := 0, เมื่อ i < n, เพิ่ม i ขึ้นทีละ 1, ทำ:
  กำหนดสแต็ก s.
  ถ้า not v1[i] ไม่เป็นศูนย์, แล้ว:
    dfs(i, pk, v1, s)
    ถ้า not s ว่าง, แล้ว:
      resa := resa * (f[ขนาดของ s])
      resa := resa mod modval
สำหรับ i := 0, เมื่อ i < n, เพิ่ม i ขึ้นทีละ 1, ทำ:
  กำหนดสแต็ก s
  ถ้า not v2[i] ไม่เป็นศูนย์, แล้ว:
    dfs(i, e, v2, s)
    ถ้า not s ว่าง, แล้ว:
      resb := resb * (f[ขนาดของ s])
      resb := resb mod modval
พิมพ์((resa * resb) mod modval)

ตัวอย่าง

ลองดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -

#include <bits/stdc++.h> using namespace std; #define modval 998244353 const int INF = 1e9; void dfs(int k, vector<int> ver[], bool visited[], stack<int> &s) {    if(visited[k])       return;    visited[k] = true;    s.push(k);    for(vector<int> :: iterator j = ver[k].begin(); j!=ver[k].end(); j++)       dfs(*j, ver, visited, s); } void solve(int n, int k, vector<vector<int>> mat) {    int f[51];    f[0] = 1;    for(int i = 1; i <= 50; i++) {       f[i] = (i * f[i-1]) % modval; } vector<int> e[n]; vector<int> pk[n]; for(int i = 0; i < n; i++) {     for(int j = i + 1;j < n; j++) {       int chk = 0;       for(int l = 0; l < n; l++){          if((mat[i][l] + mat[j][l]) > k) {             chk = 1;             break;          }       }       if(chk==0) {          pk[i].push_back(j);          pk[j].push_back(i);       }       chk = 0;       for(int l = 0;l < n; l++) {          if((mat[l][i] + mat[l][j]) > k){             chk = 1;             break;           }       }       if(chk == 0) {           e[i].push_back(j);         e[j].push_back(i);       }     } } int resa = 1, resb = 1; bool v1[n], v2[n]; for(int i = 0; i < n; i++) {    v1[i] = false;     v2[i] = false; } for(int i = 0;i < n; i++) {    stack<int> s;    if(!v1[i]) {       dfs(i, pk, v1, s);       if(!s.empty()) {           resa *= (f[s.size()]) % modval;           resa %= modval;       }     } } for(int i = 0 ;i < n; i++) {    stack<int> s;    if(!v2[i]){       dfs(i, e, v2, s);       if(!s.empty()) {          resb *= (f[s.size()]) % modval;          resb %= modval;       }    } } cout<< (resa * resb) % modval; } int main() {    int n = 3, k = 15;    vector<vector<int>> mat = {{4, 3, 6}, {5, 9, 7}, {1, 2, 8}};    solve(n, k, mat);    return 0; }

อินพุต

3, 15, {{4, 3, 6}, {5, 9, 7}, {1, 2, 8}}

เอาต์พุต

36