bzoj 1709

1709: [Usaco2007 Oct]Super Paintball超級彈珠

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 342  Solved: 266
[Submit][Status][Discuss]

Description

奶牛們最近從著名的奶牛玩具製造商Tycow那裏,買了一套仿真版彩彈遊戲設備(類乎於真人版CS)。 Bessie把她們玩遊戲草坪劃成了N * N(1 <= N<= 100)單位的矩陣,同時列出了她的 K (1 <= K <= 100,000)個對手在草地上的位置。然後她拿着這張表來找你,希望你能幫她計算一個數據。 在這個遊戲中,奶牛可以用一把彈珠槍向8個方向中的任意一個射出子彈。8個方向分別是:正北,正南,正東,正西,以及夾在這4個正方向之間的45°角:東北,東南,西北,西南方向。 Bessie望你告訴她,如果她想站在一個可以射到她的所有對手的格子上,那麼她有多少種選擇。當然,貝茜可以跟她的某一個對手站在同一個格子上,並且在這種情況下,你可以認爲貝茜能射到跟她站在同一格子裏的對手。

Input

* 第1行: 2個用空格隔開的整數:N和K

* 第2..K+1行: 第i+1行用2個以空格隔開整數R_i和C_i,描述了第i頭奶牛的位置,表示她站在第R_i行,第C_i列

Output

* 第1行: 輸出1個整數,表示如果Bessie可以選擇的格子的數目。

Sample Input

4 3
2 1
2 3
4 1

輸入說明:

牧場被劃分成了4行4列。Bessie的站位必須保證她能射到站在(2,1),(2,3)

以及(4,1)的奶牛:

. . . .
C . C .
. . . . <--- 奶牛們的位置
C . . .

Sample Output

5

輸出說明:

Bessie可以選擇站在以下格子中的任意一個:(2,1),(2,3),(3,2),(4,1),
以及(4,3)。下右圖中,Bessie與其他牛共同佔有的格子被標記爲'*':
. . . . . . . .
B . B . ---\ * . * .
. B . . ---/ . B . .
B . B . * . B .

這題思維挺巧妙的,採取了逆向覆蓋的思維,計算每個位置被覆蓋的次數,而不是正向去枚舉每個點,覆蓋了多少點。其中主對角線用x-y+n表示,+n是爲了防止出現負數,副對角線用x+y表示,可以證明任意在同一條主對角線的格子的座標滿足x-y+n相等,同理任何在副對角線的格子滿足x+y相等,因此可以利用這個來確定某個格子是否被對角線的其他格子覆蓋,這裏還有一個問題,就是最後枚舉每個格子時,若該格子本來就有一個牛,那麼覆蓋應爲k-1,而該格子沒有牛時,覆蓋應爲k,這樣分兩種情況討論也可以,這裏加一點優化,對pos[x][y]加1,這樣在原先式子上減去3倍的pos[x][y],那麼未覆蓋時,pos=0,因此相當於沒減,就是被其他k個覆蓋,若本身覆蓋,則pos=1,此時相當於減3,被自身覆蓋+4,被其餘k-1覆蓋,+(k-1),最終4+(k-1)-3也剛好爲k,真是太巧妙了!

代碼:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

int r[110],c[110],a[210],b[210];
int pos[110][110];
int ans;
int main()
{
    int n,k,x,y;
    scanf("%d%d",&n,&k);
    for(int i=0;i<k;i++){
        scanf("%d%d",&x,&y);
        r[x]++,c[y]++,a[x+y]++,b[x-y+n]++;
        pos[x][y]++;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(r[i]+c[j]+a[i+j]+b[i-j+n]-3*pos[i][j]==k)
                ans++;
    printf("%d\n",ans);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章