直接模拟
#include
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair pii;
int n,m,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int a,b;
cin >> n >> a >> b;
vector v(n + 1);
for(int i = 1;i <= n; i++) cin >> v[i];
int ans = 0;
for(int i = 1;i <= n; i++)
{
if(v[i] == a+b)
{
ans = i;
break;
}
}
cout << ans << '\n';
return 0;
}
哎,本以为会很顺利做过,没想到题目看错了,整体移动,以为是某一行或某一列移动,一定要多花点时间熟悉英文题面(英语太拉了),那么就直接枚举所有移动的情况H*W,再与另外一个数组是否匹配。时间复杂度O(),不过我用了map复杂度高了一点点,思路有了,就看你怎么实现。
#include
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair pii;
int n,m,k;
char a[50][50],b[50][50];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for(int i = 0;i < n; i++) cin >> a[i];
for(int i = 0;i < n; i++) cin >> b[i];
map mp;
for(int i = 0;i < n; i++)
for(int j = 0;j < m; j++)
if(a[i][j] == '#')
{
mp[{i,j}]++;
k++;
}
for(int i = 0;i <= n; i++)
for(int j = 0;j <= m; j++) //枚举移动的所有情况
{
vector v;
for(int ii = 0;ii < n; ii++)
for(int jj = 0;jj < m; jj++)
if(b[ii][jj] == '#')
{
int l = ii + i,r = jj + j;
if(ii + i >= n) l -= n;
if(jj + j >= m) r -= m;
v.push_back({l,r});
}
int f = 1;
for(auto &x : v)
{
int l,r;
l = x.first, r = x.second;
if(!mp[{l,r}])
{
f = 0;
break;
}
}
if(f == 1 && v.size() == k) //移动后与另一个相同
{
cout << "Yes\n";
return 0;
}
}
cout << "No\n";
return 0;
}
根据题意搜索X的图形,并将size1~min(H,W)的X的个数输出。我是先判断它是否为size 1的X再去判断它的真实大小,一个模拟过程不断增加d的大小。
#include
using namespace std;
const int N = 100010,mod = 1e6+7;
typedef long long ll;
typedef pair pii;
int n,m,k;
char g[110][110];
int cnt[110];
int check(int x,int y)
{
int res = 0;
for(int i = 1;i <= 110; i++)
{
int f = 1;
for(int j = 1;j <= i; j++)
{
if(x - j < 0 || x + j >= n || y - j < 0 || y + j >= m)
{
f = 0;
break;
}
if(!(g[x - j][y - j] == '#' && g[x - j][y + j] == '#' && g[x + j][y - j] == '#' && g[x + j][y + j] == '#')) f = 0;
}
if(f) res = i;
else break;
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for(int i = 0;i < n; i++) cin >> g[i];
for(int i = 0;i < n; i++)
for(int j = 0;j < m; j++)
{
if(g[i][j] == '#' && g[i - 1][j - 1] == '#' && g[i - 1][j + 1] == '#' && g[i + 1][j - 1] == '#' && g[i + 1][j + 1] == '#')
{
// cout << i << ' ' << j << endl;
int res = check(i,j);
// cout << "res " << res << endl;
cnt[res]++;
}
}
for(int i = 1;i <= min(n,m); i++)
cout << cnt[i] << ' ';
return 0;
}
题目可能不太难(但复杂度我确实很迷),但数据类型爆掉真的要注意,不然搞了老半天还不知道错哪了,首先要知道筛多大范围的质数,,令a = 2,b = 3,n <= 1e12,可得c <= 288,675,筛3e5的质数即可。我就想了直接枚举所有可能,并进行了一系列的剪枝,最后好像也确实过了。看官方题解O(),我们对答案的记录从最后给的样例确实不会超时。
#include
using namespace std;
typedef long long ll;
typedef pair pii;
const int N = 300010,mod = 1e9+7;
ll n,m;
int primes[N],cnt;
int st[N];
ll s[N];
void get_primes()
{
for(int i = 2;i <= N; i++)
{
if(!st[i])
{
primes[cnt++] = i;
}
for(int j = 0;primes[j] <= N / i; j++)
{
st[primes[j] * i] = 1;
if(i % primes[j] == 0) break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
get_primes();
cin >> n;
ll ans = 0;
for(int i = 0;i < cnt; i++)
{
if(1ll * primes[i] * primes[i] > n) break;
for(int j = i + 1;j < cnt; j++)
{
if(1ll * primes[i] * primes[i] * primes[j] > n) break;
for(int k = j + 1;k < cnt; k++)
{
ll res = 1ll * primes[i] * primes[i] * primes[j] * primes[k];
if(res > n) break;
res *= primes[k];
if(res <= n)
{
ans++;
}
else break;
}
}
}
cout << ans << '\n';
return 0;
}