【题目链接】A - Horizon (atcoder.jp)
思路:模拟
【代码实现】
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
int main()
{
double n;
scanf("%lf", &n);
printf("%.9lf\n", sqrt(n * (12800000.0 + n)) );
return 0;
}
【题目链接】B - Integer Division (atcoder.jp)
思路:模拟
【代码实现】
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
int main()
{
LL n;
cin >> n;
if(n < 0)
{
if(abs(n) / 10 * 10 == abs(n)) cout << "-" << abs(n)/10;
else cout << "-" << abs(n)/10 + 1;
}
else
cout << n/10;
return 0;
}
【题目链接】C - Knight Fork (atcoder.jp)
思路:判断八个方向上的某一个点,到所给的两个点的距离是否相等
知识点:模拟 + 数学
【代码实现】
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
int dx[8] = {1,2,2,1,-1,-2,-2,-1};
int dy[8] = {2,1,-1,-2,-2,-1,1,2};
bool check(int x1, int y1, int x2, int y2)
{
for(int i = 0; i < 8; i ++)
{
LL a = x1 + dx[i], b = y1 + dy[i];
LL xx1 = a - x1, yy1 = b - y1, xx2 = a - x2, yy2 = b - y2;
if(xx1 * xx1 + yy1 * yy1 == 5 && xx2 * xx2 + yy2 * yy2 == 5) return true;
}
return false;
}
int main()
{
LL x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
if(check(x1, y1, x2, y2)) puts("Yes");
else puts("No");
return 0;
}
【题目链接】 D - Prime Sum Game (atcoder.jp)
思路:判断ab中是否存在一个数,若这个数与cd中的任何一个数的和都不是质数说明前者获胜,反之后者胜
知识点:模拟 + 素数的判断
【代码实现】
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
const int N = 110;
typedef long long LL;
bool is_prime(int n)
{
if(n < 2) return false;
for(int i = 2; i <= n / i; i ++)
if(n % i == 0) return false;
return true;
}
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
// 判断a~b中是否存在一个数,若这个数与c~d中的任何一个数的和都不是质数说明前者获胜
for(int i = a; i <= b; i ++)
{
bool flag = true;
for(int j = c; j <= d; j ++)
{
if(is_prime(i + j))
flag = false;
}
if(flag)
{
puts("Takahashi");
return 0;
}
}
puts("Aoki");
return 0;
}
【题目链接】E - Subtree K-th Max (atcoder.jp)
题意:求以v为根节点的子树的第k大的数
思路:递归深搜每一个节点(从根节点开始往下),将以该节点为根节点的所有子元素存储下来(前20个),然后进行降序排序,这样就得到了所有节点的前20个数的降序序列,输出第k大即可。
知识点:树/图的深度遍历 + 排序
为了方便对每一个节点的前20个元素进行存储和排序,我们用vector的二维数组来实现!
【代码实现】
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
int h[N], e[N], ne[N], idx;
int w[N];
vector<int> subtree[N]; // 存储所有子树(包含当前节点),前20大的数
int n, q;
bool cmp(int a, int b)
{
return a > b;
}
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int u, int fa)
{
subtree[u].push_back(w[u]);
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];// 拿到节点编号
if(j != fa)// 保证只会往下搜索
{
dfs(j, u);
for(auto x : subtree[j]) subtree[u].push_back(x);
}
}
sort(subtree[u].begin(), subtree[u].end(), cmp);// 降序排序
if(subtree[u].size() > 20) subtree[u].resize(20);// 限制大小:只取前20个数
}
int main()
{
memset(h, -1, sizeof h);
cin >> n >> q;
for(int i = 1; i <= n; i ++) cin >> w[i];// 存放1~n节点的点权
for(int i = 1; i < n; i ++)
{
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
dfs(1, 0);// 从1节点开始,第二个参数为父节点,节点1不存父节点
while(q --)
{
int v, k;
cin >> v >> k;
cout << subtree[v][k - 1] << endl;// 数组下标从0开始
}
return 0;
}