放假把钱包里的钱都放生了QAQ,明明钱还没有拿来打竟赛的水漂;
A - Lake Counting S
洛谷:P1596;
数据量不大的连通器类搜索,可以用笨办法搜过去;
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, m, cnt, b[N][N];
int xi[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int yi[] = {0, 1, 1, 1, 0, -1, -1, -1};
string a[N];
void dfs(int x, int y)
{
b[x][y] = cnt;
for(int i = 0; i < 8; i ++)
{
int ax = x + xi[i], ay = y + yi[i];
if(ax >= n || ay >= m || ax < 0 || ay < 0) continue;
if(a[ax][ay] != 'W' || b[ax][ay]) continue;
dfs(ax, ay);
}
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i ++) cin >> a[i];
for(int i = 0; i < n; i ++)
for(int j = 0; j < m; j ++)
if(a[i][j] == 'W' && b[i][j] == 0)
{
cnt ++;
dfs(i, j);
}
cout << cnt;
}
成功AC;
B - 填涂颜色
洛谷:P1162;
因为被1包围的小岛一定只有一个,那只要把外面的0全染上色就可以了!
使矩阵周围额外围上一圈0, 然后从(0,0)开始染色;
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
int n, a[N][N];
int xi[] = {-1, 0, 1, 0};
int yi[] = {0, 1, 0, -1};
void dfs(int x, int y)
{
a[x][y] = 2;
for(int i = 0; i < 4; i ++)
{
int ax = x + xi[i], ay = y + yi[i];
if(ax > n + 1 || ay > n + 1 || ax < 0 || ay < 0) continue;
if(a[ax][ay] != 0) continue;
dfs(ax, ay);
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
cin >> a[i][j];
dfs(0, 0);
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
if(a[i][j] == 0) cout << 2 << ' ';
else if(a[i][j] == 1) cout << 1 << ' ';
else cout << 0 << ' ';
}
cout << endl;
}
}
大功告成!
C - 字串变换
洛谷:P1032;
一个按部就班的广搜,主要是第五个点MLE了,于是临时拉了个map来判重;
#include <bits/stdc++.h>
#define FOR_(I, S, N) for (int I=(S), END=(N); I<=END; I++)
using namespace std;
map<string, int> m;
queue<string> q;
queue<int> p;
string a, b;
string ta[10], tb[10];
int t = 1, res;
int main()
{
cin >> a >> b;
while(cin >> ta[t] >> tb[t]) ++ t;
-- t;
q.push(a);
p.push(0);
while(!q.empty() && q.front() != b && p.front() <= 10)
{
if(m[q.front()])
{
q.pop();
p.pop();
continue;
}
m[q.front()] = 1;
FOR_(i, 1, t)
{
string s = q.front();
int k = 0;
while(1)
{
k = s.find(ta[i], k);
if(k == -1) break;
string s1 = s;
s1.replace(k, ta[i].length(), tb[i]);
q.push(s1);
p.push(p.front() + 1);
k ++;
}
}
q.pop();
p.pop();
}
if(p.front() <= 10 && !q.empty()) cout << p.front();
else cout << "NO ANSWER!";
}
还算是短且简单的吧!
D - Corn Maze S
洛谷:P1825;
广搜走迷宫的变种,区别在于传送门必须传送而不能路过,那就会导致这种情况:
# # # # #
# # A . #
# # # # #
# @ . A =
# # # # #
因为出口被传送门堵住了,所以必须先进传送门去上面,再返回。
所以我们的标志性数组必须做出相应的改变
#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
const int N = 330;
typedef pair<int, int> pii;
queue<pii> q;
int n, m, a[N][N];
char mp[N][N];
pii st, up[26][2];
int xi[] = {-1, 0, 1, 0};
int yi[] = {0, 1, 0, -1};
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++)
{
getchar();
for(int j = 1; j <= m; j ++)
{
mp[i][j] = getchar();
if(mp[i][j] == '@') st.f = i, st.s = j;
if(isupper(mp[i][j]) && up[mp[i][j] - 'A'][0].f == 0) up[mp[i][j] - 'A'][0].f = i, up[mp[i][j] - 'A'][0].s = j;
else if(isupper(mp[i][j]) && up[mp[i][j] - 'A'][1].f == 0) up[mp[i][j] - 'A'][1].f = i, up[mp[i][j] - 'A'][1].s = j;
}
}
a[st.f][st.s] = 1;
q.push(st);
while(!q.empty())
{
pii now = q.front();
q.pop();
int x = now.f, y = now.s;
for(int i = 0; i < 4; i ++)
{
int nx = x + xi[i], ny = y + yi[i];
if(isupper(mp[nx][ny]))
{
int d = mp[nx][ny] - 'A';
if(up[d][0].f == nx && up[d][0].s == ny) nx = up[d][1].f, ny = up[d][1].s;
else nx = up[d][0].f, ny = up[d][0].s;
}
if(mp[nx][ny] == '#' || a[nx][ny]) continue;
if(mp[nx][ny] == '=')
{
cout << a[x][y];
return 0;
}
a[nx][ny] = a[x][y] + 1;
pii ne;
ne.f = nx, ne.s = ny;
q.push(ne);
}
}
}
E - 奇迹
洛谷:P5440;
开了个 1e9 的数组来线性筛(笑死)
随后吸取教训反过来推(已知8位数素数不超过53000个)
都写在注释里了
#include<bits/stdc++.h>
#define FOR_(I, S, N) for (int I=(S), END=(N); I<=END; I++)
using namespace std;
const int C = 1e9;
typedef long long ll;
const int d[] = {0,3,5,7,11,13,17,19,23,29,31,37}; //小于日期的质数
const int m[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; //每个月
int mp[100], yp[60000];
int T, t, cnt, res;
char s[10];
bool ip(int x){ // is_prime 函数
for (int i = 2; i * i <= x; i ++)
if (x % i == 0) return 0;
return 1;
}
int main() {
//找出所有 月 + 日 是质数的记录在 month_prime 数组中
for (int i = 1; i <= 12; i ++)
for (int j = 1; d[j] <= m[i]; j ++)
if (ip(i * 100 + d[j]))
mp[++ t] = i * 100 + d[j];
//特判所有 闰年 + 0299 是质数的记录在 year_prime 数组中
for (int i = 4; i < 10000; i += 4)
if ((i % 100 || !(i % 400)) && ip(i * 10000 + 229))
yp[++ cnt] = i * 10000 + 229;
//找出所有 年 + 月 + 日 是质数的记录在 year_prime 数组中
for (int i = 1; i < 10000; i ++)
for (int j = 1; j <= t; j ++)
if (ip(i * 10000 + mp[j]))
yp[++ cnt] = i * 10000 + mp[j];
cin >> T;
while (T--) {
cin >> (s + 1);
res = 0;
for (int i = 1; i <= cnt; i++){
int q = yp[i], fl = 1;
for (int j = 8; fl && j; j--, q /= 10)
if (s[j] != '-' && s[j] - '0' != q % 10)
fl = 0;
res += fl;
}
cout << res << endl;
}
return 0;
}
五一的早上(?)一点半写完,劳动节快乐!