总结:今天把该刷的题刷完了,明天休息一天
P1596 [USACO10OCT] Lake Counting S
思路:循环一遍数组,遇到w,ans加一,同时dfs八个方向将这一水潭做标记
ac:
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using std::cin;
using std::cout;
using std::endl;
#define N 110
char a[N][N];
int abook[N][N];
int n, m;
int next[8][2] = { {1,0},{-1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,1},{1,-1} };
void dfs(int x, int y) {
abook[x][y] = 1;
for (int i = 0; i <= 7; i++) {
int x1 = x + next[i][0];
int y1 = y + next[i][1];
if (x1<1 || x1>n || y1<1 || y1>m || abook[x1][y1]||a[x1][y1]=='.')continue;
dfs(x1, y1);
}
}
int main() {
int ans=0;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
cin >> a[i][j];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (a[i][j] == 'W' && abook[i][j] == 0) {
ans++;
dfs(i, j);
}
}
cout << ans;
}
P2895 [USACO08FEB] Meteor Shower S
思路:求最短时间,bfs,弄一个数组,所有被撞击和波及的格子打上撞击时间的标记,初始化数组为-1,所以走到-1就是最短时间了
ac:
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using std::cin;
using std::cout;
using std::endl;
using std::pair;
using std::queue;
struct point {
int x, y, t, step,visit;
}ps[1005][1005];
int main() {
int m,x,y,t,tx,ty;
int next[5][2] = { {0,1},{0,-1},{1,0},{-1,0},{0,0} };
cin >> m;
memset(ps, -1, sizeof(ps));
for(int i=0;i<1000;i++)
for (int j = 0; j < 1000; j++) {
ps[i][j].x = i;
ps[i][j].y = j;
}
for (int i = 0; i < m; i++) {
cin >> x >> y >> t;
for (int j = 0; j <= 4; j++) {
int x1 = x + next[j][0];
int y1 = y + next[j][1];
if (x1 < 0 || y1 < 0)continue;
if (ps[x1][y1].t == -1 || ps[x1][y1].t > t)
ps[x1][y1].t = t;
}
}
queue<point>q;
ps[0][0].visit = 1;
ps[0][0].step = 0;
q.push(ps[0][0]);
while (!q.empty()) {
point t = q.front();
q.pop();
for (int i = 0; i <= 3; i++) {
int x2 = t.x + next[i][0];
int y2 = t.y + next[i][1];
if ( x2<0 || y2 < 0 || ps[x2][y2].visit == 1)continue;
if (ps[x2][y2].t == -1)
{
cout << t.step + 1;
return 0;
}
if (t.step + 1 < ps[x2][y2].t) //下一步要比流星落下小才能走
{
ps[x2][y2].visit = 1;
ps[x2][y2].step = t.step + 1;
q.push(ps[x2][y2]);
}
}
}
cout << -1;
}
P2036 [COCI 2008/2009 #2] PERKET
思路:算是一道比较简单的dfs了,酸度是累乘,苦度是累加,然后每次可以选要或者不要
ac:
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using std::cin;
using std::cout;
using std::endl;
using std::pair;
using std::queue;
int n,s[20],b[20];
int max = 9999999;
void dfs(int suan, int ku, int step) {
if (step == n) {
int temp = abs(suan - ku);
if (temp<max&&ku!=0)
max =temp;
return;
}
step++;
dfs(suan * s[step], ku + b[step], step);
dfs(suan , ku , step);
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s[i] >> b[i];
}
dfs(1, 0, 0);
cout << max;
}
P1825 [USACO11OPEN] Corn Maze S
这道题是一道做起来很舒服的bfs了,思路都写在代码里的注释了
ac:
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using std::cin;
using std::cout;
using std::endl;
using std::pair;
using std::queue;
int n, m;
int next[4][2] = { {0,1},{0,-1},{1,0},{-1,0} }; //移动
struct point {
int x, y, step;
};
struct {
int x1, y1; //传送点
int x2, y2; //传送点
}s[100];
char a[305][305];
int main() {
queue<point>q;
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
char temp = a[i][j];
if (temp >= 'A' && temp <= 'Z')
{
if (s[temp].x1 == 0)
{
s[temp].x1 = i; //标记传送点
s[temp].y1 = j;
}
else {
s[temp].x2 = i; //标记传送点
s[temp].y2 = j;
}
}
else if (temp == '@') //起点入队
{
q.push(point{i,j,0});
a[i][j] = '#';
}
}
while (!q.empty()) {
point t = q.front();
q.pop();
for (int i = 0; i <= 3; i++) {
int x2 = t.x + next[i][0];
int y2 = t.y + next[i][1];
if (x2<1 || y2<1 || x2>n || y2>m||a[x2][y2]=='#')continue;
if (a[x2][y2] == '.')
{
q.push(point{ x2,y2,t.step + 1 }); //遇到草地可走入队
a[x2][y2] = '#';
continue;
}
if (a[x2][y2] == '=')
{ //到出口输出并结束程序
cout << t.step + 1;
return 0;
}
if (x2 == s[a[x2][y2]].x1 && y2 == s[a[x2][y2]].y1) //遇到传送点传送
{
q.push(point{ s[a[x2][y2]].x2,s[a[x2][y2]].y2 ,t.step + 1 });
continue;
}
else if (x2 == s[a[x2][y2]].x2 && y2 == s[a[x2][y2]].y2) //遇到传送点传送
{
q.push(point{ s[a[x2][y2]].x1,s[a[x2][y2]].y1 ,t.step + 1 });
continue;
}
}
}
}