POJ 3034 Whac-a-Mole(三維dp+處理小技巧)
題目感覺不錯,以後還得再做做。
題意:打地鼠,n*n的棋盤,每秒特定的格子上會有地鼠出沒。給一個錘子,比如錘子前一次在(x1, y1),現在移動到
(x2, y2)。則它可以打掉(x1, y1) -> (x2, y2)連線上的所有地鼠。錘子每次最多移動的距離為d。求最後最多能打到
多少個地鼠。
主要的思路就是用該點求出與該點相鄰的點的狀態。
dp[t][x][y]表示時間為t是,錘子在(x, y)座標的最大值。列舉x,y,求t + 1時間到(xx, yy)的最優值, dis(x, y, xx,
yy) <= d。在計算(x, y) -> (xx, yy)的時候不能一個單位一個單位的加,否則會超時。dx表示x -> xx的偏移量,
dy表示y -> yy的偏移量。
處理小技巧:求出dx, dy的最大公約數tp。 dx /= tp, dy /= tp。這樣從(x, y) 到(xx, yy)時沒次x
+= dx, y += dy;
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 3179 | Accepted: 961 |
Description
![](https://i.iter01.com/images/e90d4f61354d33e518f8a6f055bf8615de0a8048a7b733f71678739d7c894f61.png)
While visiting a traveling fun fair you suddenly have an urge to break the high score in the Whac-a-Mole game. The goal of the Whac-a-Mole game is to… well… whack moles. With a hammer. To make the job easier you have first consulted the fortune teller and now you know the exact appearance patterns of the moles.
The moles appear out of holes occupying the n2 integer points (x, y) satisfying 0 ≤ x, y < n in a two-dimensional coordinate system. At each time step, some moles will appear and then disappear again before the next time step. After the moles appear but before they disappear, you are able to move your hammer in a straight line to any position (x2, y2) that is at distance at most d from your current position (x1, y1). For simplicity, we assume that you can only move your hammer to a point having integer coordinates. A mole is whacked if the center of the hole it appears out of is located on the line between (x1, y1) and (x2, y2) (including the two endpoints). Every mole whacked earns you a point. When the game starts, before the first time step, you are able to place your hammer anywhere you see fit.
Input
The input consists of several test cases. Each test case starts with a line containing three integers n, d and m, where n and d are as described above, and m is the total number of moles that will appear (1 ≤ n ≤ 20, 1 ≤ d ≤ 5, and 1 ≤ m ≤ 1000). Then follow m lines, each containing three integers x, y and t giving the position and time of the appearance of a mole (0 ≤ x, y < n and 1 ≤ t ≤ 10). No two moles will appear at the same place at the same time.
The input is ended with a test case where n = d = m = 0. This case should not be processed.
Output
For each test case output a single line containing a single integer, the maximum possible score achievable.
Sample Input
4 2 6 0 0 1 3 1 3 0 1 2 0 2 2 1 0 2 2 0 2 5 4 3 0 0 1 1 2 1 2 4 1 0 0 0
Sample Output
4 2
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-4
#define M 1000100
//#define LL __int64
#define LL long long
#define INF 0x7ffffff
#define PI 3.1415926535898
const int maxn = 63;
using namespace std;
int N;
int n, d, m;
struct node
{
int x, y;
double d;
} f[1010];
int dp[maxn][maxn][maxn];
int mp[maxn][maxn][maxn];
bool cmp(node a, node b)
{
return a.d < b.d;
}
void init()
{
N = 0;
for(int i = -5; i <= 5; i++)
{
for(int j = -5; j <= 5; j++)
{
if(i*i + j*j <= 25)
{
f[N].x = i;
f[N].y = j;
f[N++].d = sqrt((i*i*1.0)+(j*j*1.0));
}
}
}
sort(f, f+N, cmp);
}
int Sum(int t, int x, int y, int xx, int yy, int dx, int dy)
{
int cnt = 0;
while(1)
{
cnt += mp[t][xx][yy];
if(x == xx && y == yy)
break;
xx += dx;
yy += dy;
}
return cnt;
}
bool judge(int x, int y)
{
if(x < 0 || x >= n+2*d+1 || y < 0 || y >= n+2*d+1)
return false;
return true;
}
int main()
{
init();
while(cin >>n>>d>>m)
{
if(!n && !d && !m)
break;
int x1, y1, t;
int max_t = 0;
memset(dp, 0, sizeof(dp));
memset(mp, 0, sizeof(mp));
for(int i = 0; i < m; i++)
{
cin >>x1>>y1>>t;
mp[t][x1+d][y1+d] = 1;
max_t = max(max_t, t);
}
max_t++;
for(int tt = 1; tt < max_t; tt++)
{
for(int x = 0; x < 2*d+n+1; x++)
{
for(int y = 0; y < 2*d+n+1; y++)
{
for(int i = 0; i < N && double(d) >= f[i].d; i++)
{
int dx = f[i].x;
int dy = f[i].y;
int xx = x+dx;
int yy = y+dy;
if(!judge(xx, yy))
continue;
int ans;
if(i == 0)//(0,0)這種情況
ans = mp[tt][x][y];
else
{
int s = __gcd(abs(dx), abs(dy));
dx /= s;
dy /= s;
ans = Sum(tt, xx, yy, x, y, dx, dy);
}
dp[tt+1][xx][yy] = max(dp[tt][x][y]+ans, dp[tt+1][xx][yy]);
}
}
}
}
int Max = 0;
for(int i = d; i < d+n; i++)
for(int j = d; j < d+n; j++)
if(Max < dp[max_t][i][j])
Max = dp[max_t][i][j];
cout<<Max<<endl;
}
return 0;
}
相關文章
- 防抖動處理和節流 小技巧
- pat處理輸入輸出小技巧(待更新)
- 安全運維小技巧運維
- 【封裝小技巧】列表處理函式的封裝封裝函式
- 程式設計小技巧之 Linux 文字處理命令(二)程式設計Linux
- poj--1625Censored!+AC自動機上的dp+大數
- 【封裝小技巧】數字處理函式的封裝封裝函式
- Linux文字處理技巧分享Linux
- 二、淺談 JSON 處理技巧JSON
- photoshop常用圖片處理技巧
- 分組(狀壓dp+技巧:快速列舉子集)
- POJ2502 Subway【最短路+技巧】
- 圖觀™引擎開發小技巧——三維場景地標點繪製
- 小技巧:不用任何媒體處理軟體進行視訊壓縮
- Liunx運維(三)-檔案過濾及內容編輯處理運維
- flutter demo (三):json處理FlutterJSON
- ORACLE GoldenGate 使用技巧-容錯處理等OracleGo
- 點贊處理的一些小技巧
- 【python技巧】文字處理-re庫字元匹配Python字元
- 處理 Linux 檔案的 3 個技巧Linux
- 處理 JS 中 undefined 的 7 個技巧JSUndefined
- YYImage 原始碼剖析:圖片處理技巧原始碼
- Flask開發技巧之異常處理Flask
- 列舉子集+預處理最佳化dp+貪心視角轉化成可做dp
- 小程式程式碼打包處理
- Transact-SQL處理小數SQL
- POJ1847 Tram【Dijkstra+思維】
- R中的迴圈多圖處理技巧
- Java 運算子詳解與字串處理技巧Java字串
- Trick:處理加減等差數列的技巧
- 遺留程式碼處理技巧與案例演示
- Shell指令碼逐行處理文字檔案技巧指令碼
- C++ 異常處理機制詳解:輕鬆掌握異常處理技巧C++
- 日常運維之TX鎖處理(一)運維
- 日常運維之TX鎖處理(二)運維
- Linux 命令列小技巧 – !歎號的用處Linux命令列
- 微信小程式資料處理微信小程式
- Hadoop小檔案的處理方式Hadoop
- 基於數字孿生智慧汙水處理三維視覺化管理系統視覺化