棋盤 K皇后
棋盤 K皇后
洛谷P2105 作為我在洛谷AC的第100題,拍照留念。
(我不會告訴你我做這道題用了9個小時的,哈哈 )
題目描述:
小 Z 最近撿到了一個棋盤,他想在棋盤上擺放 KK 個皇后。他想知道在他擺完這 KK 個皇后之後,棋盤上還有多少個格子是不會被攻擊到的。
注意:一個皇后會攻擊到這個皇后所在的那一行,那一列,以及兩條對角線。
初解此題,我的思路侷限於通過一個點的位置來找到皇后能走的位置,再用總的格子去減皇后能走的格子。
這樣想似乎很合理,如果題目的資料控制在小範圍,我一定會這樣做。但是,很不幸的是他給的資料範圍是1e5,那麼這個圖最多可以有1e10的格子,而時間限制於1s,顯然用蒟蒻的解法會超時。
下面聊聊大佬的思路:
如果通過一個點去描述一張圖,這樣做的複雜度太大。那麼反過來,為什麼不可以把圖分割成一個個小部分,再通過探究每個點對這個區域性圖的影響來確定整個圖呢?
於是就有下面的程式碼:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define N 100000
ll n, m, k;
ll x[N], y[N],vis[N];
ll color[N];
ll ans = 0;
ll step = 0;
int main()
{
cin >> n >> m >> k;
for (int i = 1; i <= k; i++)
{
cin >> x[i] >> y[i];
vis[x[i]] = 1;
}
for (int i = 1; i <= n; i++)
{
if (vis[i] == 1)
{
continue;
}
ll sum = m;
//cout << 'm' << ' ' << m << endl;
for (int j = 1; j <= k; j++)
{
//cout << "color[y[j]]= " << color[y[j]] << endl;
if (color[y[j]] != i)sum--;
//cout <<'1' <<' '<<sum << endl;
color[y[j]] = i;//致命錯誤
if (x[j] > i)
{
int len = x[j]-i;
if (y[j] -1>= len&&color[y[j]-len]!=i)
{
sum--;
color[y[j] - len] = i;
}
if (m - y[j] >= len && color[y[j] + len] != i)
{
sum--;
color[y[j] + len] = i;
}
}
//cout << '2'<<' '<<sum << endl;
if(x[j]<i)
{
int len = i-x[j];//頂級錯誤
if (y[j] -1>= len && color[y[j] - len] != i)
{
sum--;
// cout << y[j] - 1 << ' ' << len << endl;
// cout << "keneng chucuo" << endl;
color[y[j] - len] = i;
}
if (m - y[j] >= len && color[y[j] + len] != i)
{
sum--;
color[y[j] + len] = i;
}
}
// cout <<'3'<< ' '<< sum << endl;
}
//cout << '4'<<' '<<sum << endl;
ans += sum;
}
cout << ans << endl;
return 0;
}
我們把一個棋盤分解成n個行,研究每個點對該行的影響,如果這個皇后斜著走會經過這行,那我們就標記這個點,當遍歷了所有點後,那些沒有標記的點就是皇后不會經過的點,這樣這一行的不能被經過點的個數就確定了。重複操作後就可以找到這樣圖的全部未經過點了。
其實這個思路不難理解,但是思路化為程式碼確實令人難受。換句話說,就是打碼一小時,除錯八小時。
下面就來聊聊我在這道題上放的小錯誤:
1.1 建圖的錯誤
一開始我認為的棋盤是這個樣子的:
但實際上是這個樣子的:
我記得這個建圖錯誤不是第一次遇到,但還是忘記了。
在解決了這個問題後,我覺得我一定能過了。但是垃圾oj又一次讓我感受到了社會的險惡,全面WA了。於是我開啟了瘋狂除錯之路,這一調又是3小時。
最後我是通過自己建圖來找錯的:
根據圖來看程式碼,最後發現我有幾處的 j 寫成了 i 。直接吐血的操作,哎。
由此題也告訴我們,最好不要讓j 和 i 出現在同一個部分,特別是 i 和 j 要不斷變化和使用的時候,因為一個不小心就是 8個小時調程式碼的歡樂時光。
相關文章
- I. 棋盤
- 棋盤問題
- 棋盤覆蓋
- 棋盤問題 POJ - 1321
- 棋盤覆蓋問題
- 電子棋盤(二)——戰棋地形的多樣性
- turtle繪製國際象棋棋盤
- poj 1321 棋盤問題 回溯 JavaJava
- POJ1321棋盤問題(DFS)
- N皇后和N皇后2
- N 皇后
- YCOJN皇后
- 資料結構:稀疏棋盤的實現資料結構
- Processing 網格紋理製作(棋盤格)
- 9路棋盤識別-程式碼備份
- 16×16大小棋盤的五子棋小程式 Java實現Java
- 迴圈_推導式_繪製棋盤_函式函式
- 分治演算法-求解棋盤覆蓋問題演算法
- 51,N皇后
- python八皇后Python
- 後疫情時代,城市更需盤活資料治理與運營這盤棋
- 發行USDD,孫宇晨在下一盤大棋
- 棋盤完美覆蓋數(小規模原理實現)
- 怎樣解題|題3.2.14:填充國際象棋棋盤
- N皇后問題
- 7-22 n queens (10分) 八皇后(n皇后)問題
- Processing 網格(棋盤格)無限偏移紋理動畫動畫
- 20241201: 51. N 皇后
- 藍橋杯-N皇后
- 八皇后||演算法演算法
- 52. N皇后 II
- 【每日一題】 688. 騎士在棋盤上的機率每日一題
- 怎樣解題|題3.3.28:國際象棋棋盤上的車
- 一組簡單一點的題目(六) B – 小兔的棋盤
- 洛谷八皇后問題
- LeetCode 52. N皇后 IILeetCode
- 演算法:N皇后二演算法
- 八皇后問題python解法Python