看起來挺簡單,看到數據範圍了嗎?看到了:對於100% 的數據,N1≤N≤109;1≤K≤106;1≤Ri?,Ci?≤N。ios
死心了嗎?是真的有點絕望。第一反應就是:桶,那反正也想不出別的辦法了,咱們就用桶試試吧。優化
通過畫圖推算以後,咱們能夠獲得一個公式:(n*n)-(n-chang)*(n-clie)spa
n是棋盤的邊長,chang是有幾行被攻擊了(不算重複的),clie是有幾列被攻擊了(也不算重複的)3d
推算過程:n-chang是算有幾行沒有被攻擊,n-clie是算有幾列沒有被攻擊,把這兩個相乘就能夠獲得沒有被車攻擊的面積。code
再用n*n(也就是棋盤的總面積)減去沒有被車攻擊的面積,就能夠獲得被車攻擊的面積了。blog
代碼以下:排序
#include<iostream> #include<cstdio> #include<map> using namespace std; long long hang[1000010],lie[1000010];//開大點總沒壞處 long long n,k,a,b,chang=0,clie=0; int main(){ scanf("%lld%lld",&n,&k);//用scanf和printf會更快點 for(int i=0;i<k;i++){ scanf("%lld%lld",&a,&b); if(hang[a]!=1){ chang++; hang[a]=1; } if(lie[b]!=1){ clie++; lie[b]=1; }//用桶來標記,若是這一列是第一次被攻擊那麼就讓clie++,若是這一行是第一次被攻擊那麼就讓chang++ } printf("%lld",(n*n)-((n-chang)*(n-clie)));//公式 }
評測結果:60分,有4個點RE了it
嗯,進步了,那就讓咱們接着優化。io
既然RE是由於桶,那麼咱們就想個能把桶替換掉的辦法for循環
此次仍是要請出咱們的救星——sort
先輸入,而後用sort排序,最後再用for循環遍歷判斷。
由於sort一遍後他會大小排序,而後咱們用for循環遍歷判斷前一個數若是不一樣於後面一個數(也就是有沒有算過的行或列),就讓chang或clie++,最後再套用公式,就能夠解決桶RE的問題了。
AC代碼以下:
#include<iostream> #include<cstdio> #include<map> #include<algorithm> using namespace std; long long hang[1000010],lie[1000010]; long long n,k,a,b,chang=0,clie=0; int main(){ scanf("%lld%lld",&n,&k);//用scanf和printf讀入和輸出會更快點 for(int i=0;i<k;i++){ scanf("%lld%lld",&hang[i],&lie[i]); } //分別把行和列sort一遍 sort(hang,hang+k); sort(lie,lie+k); for(int i=0;i<k;i++){//循環遍歷判斷 if(hang[i]!=hang[i+1]){//若是發現沒有被攻擊過的行,就讓chang++。 chang++; } if(lie[i]!=lie[i+1]){//若是發現沒有被攻擊過的列,就讓clie++。 clie++; } } printf("%lld",(n*n)-((n-chang)*(n-clie)));//套用公式,輸出 }