一、纯质数
思路:
1.该数为质数;
2.该数由2/3/5/7组成
所以一切包含0/1/4/6/8/9的数我们都不需要额外计算
那我们先判断是质数还是由2/3/5/7组成?很明显是先判断后者
代码放下面:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n = 20210605;
int ans = 0;
vector<bool> isp(n+1, true);
isp[0]=false;
isp[1]=false;
for (int i = 2; i <= n; i++) {
if (isp[i]) {
string s = to_string(i);
if (all_of(s.begin(), s.end(), [&isp](char c) {return isp[c ^ 48]; })) {
ans++;
}
long long j = (long long)i * i;
while (j <= n) {
isp[j] = false;
j += i;
}
}
}
cout << ans;
return 0;
}
二、最少砝码
、
思路:假设只有一个砝码 1 只能得到数值1
你需要获得2 并且可以获得一个更大的值
x-1=2;x=3
(因为1是可以直接用1获得的,所以放入x后
可以同时满足前面已经满足的值+新放入的值和前面所有值的差值与和值)
简单点说:假设你前面的砝码可以存放1-n,现在放入一个x
那么这些砝码可以组合出:
1-n,(x-n)---(x-1) x---(x+n),而这一个要为连续值,则x-n=n+1
所以可以判断出
1—>1 那么下一个增加的值 x-1=1+1—>x=3
1 3—>1-(1+3) 那么下一个值 x-4=4+1—>x=9
........
x=n+n+1=2*n+1;
那么放入x后所能到达的值为 x+n=3*n+1;
代码放在下面:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n;
cin>>n;
int ans;
for(ans=1;;ans++)
{
if(pow(3,ans)-1>=2*n)break;
}
cout<<ans<<endl;
return 0;
}
三、灌溉
分析:
我们先要接收所有接收的数据,n,m是整个花园的大小。地会被分为已灌溉和未灌溉(我们把已灌溉的地赋值为1,未灌溉的赋值为0)然后会告诉你某些地方装了水管(被视为已经灌溉),(下文我称被灌溉的的地为被感染的地)初始大概的图是这样,图中的1是题目随机装水管的位置(图中的1是随机取的)。(注意此时时间还是0)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- 题目说了,被灌溉的地,一秒钟会把周围上下左右都变成灌溉的状态,如果经过一秒钟以后图就变成了这样
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 - 每一秒钟,每个1都会把周围的0变成1。上面红色的1,就是被黑色1从0变成了1。然后下一秒钟继续如此
- 暴力做法:我们可以每一秒钟都从头到尾把花园遍历一遍,如果,一块地是1我就把它周围都变成1。这样下去时间复杂度肯定非常高,但这只是我们最朴素的想法。
- 优化做法:我注意看上图黑色的1,下一秒钟它还有用吗?没有了,因为第一秒它周围已经全部被它变成1了,第二秒再让他变一遍完全没有意义了!第二秒是上图红色的1去感染周围的地
就变成了这个样子。再下来是蓝色去继续感染,红色也变的没有用了,因为它已经将周围的感染过了。
所以这里最核心的就是:这一秒被感染的地,下一秒去感染其他的地。我们每次记录下这一次感染的地,下次就可以自己拿这些地去感染其他的地。而不需要每次都从头到尾的去遍历花园,把这些黑色和红色的地再去重复感染一遍周围的地,没有意义。
注意事项:在这遍历的过程中,要注意边界的问题(因为花园是有大小的)。如何实现保存这一次遍历的地呢?我们可以通过队列来接收这一秒所有被感染的地,然后下一秒把这个队列里的所有地拿去感染别人。这就是多源BFS的核心(多源的意思就是同一秒内每块地都会去感染相邻的地,这是同时发生的)。当然回到最初的问题,我们可以每次都去把花园扫一遍。
- 代码放在下面了
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
queue<PII> q;
int d[N][N];
int n, m, t, k;
int bfs(){
int res = t;
//cout << res << endl;
while(q.size()){
auto t = q.front();
q.pop();
for(int i = 0; i < 4; i ++ ){
int a = t.first + dx[i];
int b = t.second + dy[i];
if(a >= 1 && a <= n && b >= 1 && b <= m && d[a][b] == -1){
d[a][b] = d[t.first][t.second] + 1;
res ++ ;
if(d[a][b] < k){
q.push({a, b});
}
}
}
}
return res;
}
int main(){
freopen("in.in", "r", stdin);
memset(d, -1, sizeof d);
cin >> n >> m >> t;
int tmp = t;
while(tmp -- ){
int x, y;
cin >> x >> y;
q.push({x, y});
d[x][y] = 0;
}
cin >> k;
cout << bfs();
return 0;
}