pezhzh的快乐寒假作业[2024/1/20]

放假把钱包里的钱都放生了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;
}

五一的早上(?)一点半写完,劳动节快乐!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值