看起來挺簡單,看到資料範圍了嗎?看到了:對於100% 的資料,n1≤n≤109;1≤k≤106;1≤ri?,ci?≤n。
死心了嗎?是真的有點絕望。第一反應就是:桶,那反正也想不出別的辦法了,我們就用桶試試吧。
經過畫圖推算之後,我們可以得到乙個公式:(n*n)-(n-chang)*(n-clie)
n是棋盤的邊長,chang是有幾行被攻擊了(不算重複的),clie是有幾列被攻擊了(也不算重複的)
推算過程:n-chang是算有幾行沒有被攻擊,n-clie是算有幾列沒有被攻擊,把這兩個相乘就可以得到沒有被車攻擊的面積。
再用n*n(也就是棋盤的總面積)減去沒有被車攻擊的面積,就可以得到被車攻擊的面積了。
**如下:
#include#include評測結果:60分,有4個點re了#include
using
namespace
std;
long
long hang[1000010],lie[1000010];//
開大點總沒壞處
long
long n,k,a,b,chang=0,clie=0
;int
main()
if(lie[b]!=1)//
用桶來標記,如果這一列是第一次被攻擊那麼就讓clie++,如果這一行是第一次被攻擊那麼就讓chang++
} printf(
"%lld
",(n*n)-((n-chang)*(n-clie)));//
公式}
嗯,進步了,那就讓我們接著優化。
既然re是因為桶,那麼我們就想個能把桶替換掉的辦法
這次還是要請出我們的救星——sort
先輸入,然後用sort排序,最後再用for迴圈遍歷判斷。
因為sort一遍後他會大小排序,然後我們用for迴圈遍歷判斷前乙個數如果不同於後面乙個數(也就是有沒有算過的行或列),就讓chang或clie++,最後再套用公式,就可以解決桶re的問題了。
ac**如下:
#include#include#include
#include
using
namespace
std;
long
long hang[1000010],lie[1000010
];long
long n,k,a,b,chang=0,clie=0
;int
main()
//分別把行和列sort一遍
sort(hang,hang+k);
sort(lie,lie+k);
for(int i=0;i//
迴圈遍歷判斷
if(hang[i]!=hang[i+1])
if(lie[i]!=lie[i+1])
}printf(
"%lld
",(n*n)-((n-chang)*(n-clie)));//
套用公式,輸出
}
P3913 車的攻擊
n n 的西洋棋棋盤上有kk 個車,第ii個車位於第r iri 行,第c ici 列。求至少被乙個車攻擊的格仔數量。車可以攻擊所有同一行或者同一列的地方。輸入格式 第1 行,2 個整數n,kn,k。接下來k 行,每行2 個整數r i,c iri ci 輸出格式 1 個整數,表示被攻擊的格仔數量。輸入...
P3913 車的攻擊 思維
題目描述 n nn times nn n 的西洋棋棋盤上有kkk 個車,第iii個車位於第rir iri 行,第cic ici 列。求至少被乙個車攻擊的格仔數量。車可以攻擊所有同一行或者同一列的地方。輸入格式 第1 行,2 個整數n,kn,kn,k。接下來k 行,每行2 個整數ri,cir i,c ...
洛谷 P3913 車的攻擊
n times nn n 的西洋棋棋盤上有kk 個車,第ii個車位於第r iri 行,第c ici 列。求至少被乙個車攻擊的格仔數量。車可以攻擊所有同一行或者同一列的地方。輸入格式 第1 行,2 個整數n,kn,k。接下來k 行,每行2 個整數r i,c iri ci 輸出格式 1 個整數,表示被攻...