CSDN周赛
上次比赛后,很久没有打,今天没事干,又打了一次(希望更好
整体来说,题目质量不低,第二题和第四题比较有难度,数论题一直不太擅长,不过这次难度不大,希望下次可以继续拿奖品。
代写匿名信
从第一行字符中是否能找到属于第二行字符,判断输出YES/NO。
注意输入是有空格的
#include <iostream>
#include <string>
using namespace std;
int st[1000000];
int main()
{
string s, t;
getline(cin, s);
cin >> t;
int n = t.size();
int m = s.size();
for (int i = 0; i < n; i++)
{
int flag = 0;
for (int j = 0; j < m; j++)
{
if (st[j] == 0 && s[j] == t[i])
{
st[j] = 1;
flag = 1;
break;
}
}
if (flag == 0)
return cout << "No", 0;
}
cout << "Yes";
return 0;
}
寻因找祖 !!! 好题 !!!
寻找因子个数为n的最小整数x
质因数分解定理中说明过,对于一个整数
x
x
x,如果
x
1
、
x
2
、
x
3
、
x
4
x_1、x_2、x_3、x_4
x1、x2、x3、x4是
x
x
x的质因子,
x
x
x可以被表示为
x
=
x
1
a
1
∗
x
2
a
2
∗
x
3
a
3
∗
x
4
a
4
x=x_1^{a_1}*x_2^{a_2}*x_3^{a_3}*x_4^{a_4}
x=x1a1∗x2a2∗x3a3∗x4a4,那么可以证明,
x
x
x的因子个数为
(
a
1
+
1
)
∗
(
a
2
+
1
)
∗
(
a
3
+
1
)
∗
(
a
4
+
1
)
({a_1} + 1)*({a_2}+1)*({a_3}+1)*({a_4}+1)
(a1+1)∗(a2+1)∗(a3+1)∗(a4+1)
根据这个定理,通过
d
f
s
dfs
dfs搜索,可以暴力出结果
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cmath>
using namespace std;
long long a[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
long long solve(long long n, long long idx)
{
if (n == 1)
return 1;
long long ans = pow(a[idx], n - 1);
for (long long i = 2; i < n; i++)
if (n % i == 0)
ans = min(ans, pow(a[idx], i - 1) * solve(n / i, idx + 1));
return ans;
}
int main()
{
int n;
std::cin >> n;
cout << solve(n, 0);
return 0;
}
小Q新式棋盘
将每一行存在suma数组中,每一列和存在sumb中,然后双重for循环遍历就可以
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int a[2000][2000];
int suma[3000], sumb[3000];
int main()
{
int n;
std::cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
suma[i] += a[i][j];
sumb[j] += a[i][j];
}
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (suma[i] < sumb[j])
ans++;
}
std::cout << ans << std::endl;
return 0;
}
拯救公主
题目比较简单,就是判断石头存在的时候,能否获取目标位置的宝物。
为判断是否可以,只需要判断
对于
m
、
m
+
1
、
m
+
2
m、m+1、m+2
m、m+1、m+2的最小公倍数是否小于目标列,如果小于目标列,说明无法走到
对于目标位置,是否被石头覆盖,如果被覆盖说明无法走到
对于初始位置,是否被石头覆盖,如果被覆盖说明无法走到
直接
f
o
r
for
for循环判断每一行就可以
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
int T;
std::cin >> T;
for (size_t i = 0; i < T; i++)
{
int m;
int x;
int y;
std::cin >> m;
std::cin >> x;
std::cin >> y;
int a, b, d;
for (int i = 0; i < m; i++)
{
char c;
cin >> c;
if (c == '*')
a = i;
}
for (int i = 0; i < m + 1; i++)
{
char c;
cin >> c;
if (c == '*')
b = i;
}
for (int i = 0; i < m + 2; i++)
{
char c;
cin >> c;
if (c == '*')
d = i;
}
int p = y % (m + x - 1);
if ((x == 1 && p == a + 1) || (x == 2 && p == b + 1) || (x == 3 && p == d + 1))
{
cout << "NO\n";
continue;
}
int flag = 1;
for (int i = 1; i < y; i++)
{
if (i % m == a && i % (m + 1) == b && i % (m + 2) == d)
{
flag = 0;
break;
}
if (i % m == 0 && i % (m + 1) == 0 && i % (m + 2) == 0)
{
break;
}
}
if (flag)
cout << "YES\n";
else
cout << "NO\n";
}
return 0;
}