【bzoj1709/Usaco2007 Oct】Super Paintball超级弹珠——递推
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 . . .
2 1
2 3
4 1
输入说明:
牧场被划分成了4行4列。Bessie的站位必须保证她能射到站在(2,1),(2,3)
以及(4,1)的奶牛:
. . . .
C . C .
. . . . <--- 奶牛们的位置
C . . .
Sample Output
5
读入的时候就把这一行、列、上升对角线(左下->右上),下降对角线的值+1。
O(n2)枚举每个点,计算这个点行、列、对角线上值的总和,若值恰好为m,则ans++。
特别的,当枚举到的点本身就有敌人时,答案会把本身算4次,要减去3*mp[i][j]。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<cmath> 5 const int N=200; 6 int n,m,mp[N][N]; 7 int h[N],s[N],xi[N],yi[N]; 8 int read(){ 9 int ans=0,f=1;char c=getchar(); 10 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 11 while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();} 12 return ans*f; 13 } 14 int main(){ 15 n=read();m=read(); 16 for(int i=1,a,b;i<=m;i++){ 17 a=read();b=read();mp[a][b]++; 18 h[a]++;s[b]++;xi[n-(b-a)]++;yi[a+b-1]++; 19 } 20 int sum=0; 21 for(int i=1;i<=n;i++){ 22 for(int j=1;j<=n;j++){ 23 int num=h[i]+s[j]+xi[n-(j-i)]+yi[i+j-1]; 24 if(mp[i][j])num-=mp[i][j]*3; 25 if(num==m)sum++; 26 } 27 } 28 printf("%d\n",sum); 29 return 0; 30 } 31