PAT 2023 冬 乙 方格填數

TLSN發表於2024-03-23

題目描述

B-4 方格填數
分數 20
作者 陳越
單位 浙江大學

2014 年哈佛-麻省理工數學競賽中一道題是這樣的:將正整數 1, 2, ..., 64 填入 8×8 的方格棋盤中,使得對任何 1i<64,i 和 i+1 都必須填在兩個具有公共邊的方格中。求棋盤上對角線中所填數的和的最大值。(注意:兩個對角線都要考慮;64 和1 也必須填在兩個具有公共邊的方格中。)
這題有點難…… 幸好我們並不要求你寫程式解決這個問題。
你的任務是:對任一給定的數字填充方案,判定其是否滿足填充的條件,並且在所有給出的方案中,找出滿足條件的、且對角線數字和最大的那個方案。

輸入格式:

輸入在一行中首先給出兩個正整數 n(100) 和 m(20),分別為棋盤的規模(即棋盤有 n×n 個方格)和輸入的方案數量。因為容易證明奇數 n 一定不存在滿足條件的解,所以題目保證給出的 n 都是偶數。
隨後給出 m 個填充方案,每個方案佔 n 行,每行 n 個不超過 n2 的數字。同行數字間以空格分隔。

輸出格式:

在一行中首先輸出滿足條件的、且對角線數字和最大的方案數。隨後一行中按照遞增序輸出這些方案的編號(編號按輸入的順序從 1 到 m)。
注意每行數字間以 1 個空格分隔,行首尾不得有多餘空格。

輸入樣例:

4 5
16 1 2 3
15 14 13 4
10 11 12 5
9 8 7 6
16 1 2 3
15 14 13 4
10 11 12 5
9 8 7 10
15 16 1 2
14 13 4 3
11 12 5 6
10 9 8 7
3 4 5 6
2 13 12 7
1 14 11 8
16 15 10 9
10 5 4 3
7 12 13 2
8 11 14 1
9 6 15 16

輸出樣例:

2
1 4
程式碼長度限制
16 KB
Java (javac)
時間限制
1100 ms
記憶體限制
256 MB
其他編譯器
時間限制
400 ms
記憶體限制
64 MB
棧限制
8192 KB

程式碼:

// 20:01 ~ 20:16

// 好像忘記判斷是否滿足條件了 
//== > 19 / 20
// dfs 判斷一下,byd,測力4格式錯誤 
#include <iostream>
#include <vector>
using namespace std;
const int N = 105;

int n,m;
int A[N][N];
int dir[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };

bool bfs(int h,int l,int val){
    int tag = 0;
    if(val == n * n)
        val = 0;
    for(int i=0;i<=3;i++){
        int x = dir[i][0] + h;
        int y = dir[i][1] + l;
        if(x >= 1 && x <= n && y >= 1 && y <= n){
            if(A[x][y] == (val+1) ){
                tag = 1;
                if(val == 0) return 1;
                return bfs(x,y,val+1) & tag;
            }
        }
    }
    return tag;
}


bool check(int row,int con){
    return bfs(row,con,1);
}

int main(){
    cin >> n >> m;
    vector<pair<int,int>> ve;
    int mx = -0x7fffffff;
    for(int z = 1;z<=m;z++){
        int row=-1,con=-1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin >> A[i][j];
                if(A[i][j] == 1){
                    row = i;
                    con = j;
                }
            }
        }
        // 判斷是否滿足條件
        if(!check(row,con)) {
            continue;
        }
        
        // 求對角線元素 
        int sum1 = 0;
        int sum2 = 0;
        for(int i=1;i<=n;i++){
            sum1 += A[i][i];
            sum2 += A[i][n-i+1];
        }
        int sum = max(sum1,sum2);
        ve.push_back(make_pair(z,sum));    
        if(sum > mx) mx = sum;
    }
    vector <int> v;
    for(int i=0;i<ve.size();i++){
        if(ve[i].second == mx){
            v.push_back(ve[i].first);
        }
    }
    
    if(v.size() == 0){
        cout << "0";
        return 0;
    }
    cout << v.size() <<endl;
    int ans = 0;
    for(auto i : v){
        if(ans != 0)
        cout << " " << i;
        else cout << i;
        ans ++;
    }
    
    
    return 0;
}

奇怪的測試點

案例四顯示格式錯誤,也不知道哪錯了

相關文章