P3913 車的攻擊

摘要:N×N 的國際象棋棋盤上有K個車,第i個車位於第R[i]行,第C[i]列。求至少被一個車攻擊的格子數量。

車能夠攻擊全部同一行或者同一列的地方。

看起來挺簡單,看到數據範圍了嗎?看到了:對於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)));//套用公式,輸出
}

以上就是我這道題的所有思路,若是有什麼不對的地方,還請各位大佬及時向我糾正。

相關文章
相關標籤/搜索