AtCoder Beginner Contest 292 [A - F](改)
A - CAPS LOCK
思路
不说,非常simple的题。转大小写肯定都会吧
代码
#include <bits/stdc++.h>
using namespace std;
string str;
int main()
{
cin >> str;
for (int i = 0; i < str.length(); i++)
if (str[i] >= 'a' && str[i] <= 'z')
str[i] = str[i] - 'a' + 'A';
cout << str << endl;
return 0;
}
B - Yellow and Red Cards
思路
纯模拟题。只要一个玩家得到了红牌,那直接让当前玩家的卡牌值变成inf。
如果是黄牌,那就+1。
最后判断有没有超过2;超过2就代表移除了。否则就没有。
代码
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1e3 + 10;
int player[N];
int n, q, op, x;
int main()
{
cin >> n >> q;
for (int i = 1; i <= q; i++)
{
cin >> op >> x;
if (op == 1)
{
player[x]++;
if (player[x] >= 2)
player[x] = -inf;
}
else if (op == 2)
player[x] = -inf;
else if (op == 3)
if (player[x] <= 2 && player[x] != -inf)
puts("No");
else
puts("Yes");
}
return 0;
}
C - Four Variables
思路
因为给定的数据范围是\(2\time 10^5\),说明必须要使用至少为\(O(n\times log_n)\)的算法。
我们不可能把每一个位置都枚举,因为这样妥妥的超时。因为这个题目想要的是\(A\times B+C\times D=n\),因此我们可以假设为\(x+y=n\),从而去枚举\(x\)和\(y\)。
这样代码就很简单了。最后的答案为\(factor[1]*factor[n-1]+factor[2]*factor[n-2]*...*factor[n-1]*factor[1]\)。
在代码中要注意,如果在求因子的时候,如果当前因子是\(\sqrt(n)\),那就说明两个因子是一样的,所以只需要加一次。否则,就是加两次(拿4举例子:如果因子枚举到1,那么还有一个4,所以再加一次。如果是2,刚好另一个也是2,因此就加一次)。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, res;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
vector<int> factor(n + 1);
for(int i = 1; i <= n; i++)
{
int t = i;
for(int j = 1; j <= t / j; j++)
if(t % j == 0)
{
factor[i] += 1;
if (j != t / j)
factor[i] += 1;
}
}
for(int i = 1; i <= n; ++i)
res += factor[i] * factor[n - i];
cout << res << endl;
return 0;
}
注意开long long
。
D - Unicyclic Components
思路
使用并查集判断是否存在环。如果在并查集中fa[i] == i,那就说明这个点可能有环。如果环的数量不等于1(可能大于可能小于但都不符合条件),输出No
,否则输出Yes
。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int fa[N], ring[N];
int n, m;
bool flag = true;
int find(int x)
{
if (fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
fa[i] = i;
for (int i = 1; i <= m; i++)
{
int a, b;
cin >> a >> b;
int f_a = find(a), f_b = find(b);
if (f_a != f_b)
{
fa[f_a] = f_b;
ring[f_b] += ring[f_a];
}
else
ring[f_b]++;
}
for (int i = 1; i <= n; i++)
if (fa[i] == i)
if (ring[i] != 1)
flag = false;
if (flag)
puts("Yes");
else
puts("No");
return 0;
}
E - Transitivity
思路
这个题很像floyd的传递闭包:就是问a到b再到c是否可行。
看了一下数据范围,最大是2000,感觉bitset优化的floyd应该问题不大。(但是我没写)
我还是使用了类似kruskal的最小生成树的方式来看是否可达。我们按照最小生成树的方式枚举每一个存下来的点。因为需要三个点可以互相到达,那就说明有三条边。如果某一个点的距离是在3以上,那就说明这三个点是联通的。这样,计数器就可以+1了。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2e3 + 10;
int h[N], e[N], ne[N], idx;
int dist[N];
bool st[N];
int n, m, a, b, res;
void add(int a, int b)
{
e[++idx] = b;
ne[idx] = h[a];
h[a] = idx;
}
void kruskal(int s)
{
memset(dist, 0, sizeof dist);
queue<int> q;
q.push(s);
dist[s] = 1;
while (q.size())
{
int t = q.front();
q.pop();
for (int i = h[t]; i; i = ne[i])
{
int j = e[i];
if (dist[j])
continue;
dist[j] = dist[t] + 1;
q.push(j);
}
}
for (int i = 1; i <= n; i++)
if (dist[i] >= 3)
res++;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
cin >> a >> b;
add(a, b);
}
for (int i = 1; i <= n; i++)
kruskal(i);
cout << res << endl;
return 0;
}
F - Regular Triangle Inside a Rectangle
思路
这个题就是一个数学题。初三数学关于求面积最值经常遇到。
这里需要有一个知识点:瓜豆原理(种瓜得瓜,种豆得豆)。这就是想说明我们可以通过一个动点的轨迹判断出另一个动点的轨迹,这样就可以求出面积的最大值。
只不过在这里实现的时候需要使用高中数学必修一里面的三角函数公式。
因为题目中是一个正三角形,假设三角形的边和矩形的边形成一个夹角\(\alpha\),那么这个角的最大值肯定是90-60=30度。这就可以把夹角\(\alpha\)的\(tan\)值算出来,判断是否能够放在矩形里面就可以了。
代码
#include <bits/stdc++.h>
using namespace std;
long double mytan, mycos, mysin;
long double res, sqrt3;
int a, b;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> a >> b;
if (a < b)
swap(a, b);
sqrt3 = sqrt(3);
mytan = 2.0 * b / a - sqrt3;
if (mytan < 0)
{
res = b / sqrt3 * 2;
cout << setiosflags(ios::fixed) << setprecision(20) << res << endl;
}
else
{
mytan = 2.0 * b / a - sqrt3;
mycos = sqrt(1 / (1 + mytan * mytan));
res = a / mycos;
cout << setiosflags(ios::fixed) << setprecision(20) << res << endl;
}
return 0;
}