A.P1551 亲戚
思路:并查集
AC代码:
(并查集暂时不会)
#include<iostream>
using namespace std;
int n, m, p, a[5005], rk[5005], m1, m2, p1, p2;
int find(int x)//查询根节点(这里没用路径压缩,因为会影响树的深度,上述有提到)
{
if (x == a[x])
{
return x;
}
else
{
return find(a[x]);
}
}
void merge(int x, int y)//按轶合并
{
int rx = find(x), ry = find(y);
if (rk[rx] <= rk[ry])
{
a[rx] = ry;
}
else if (rk[rx] > rk[ry])
{
a[ry] = rx;
}
if (rk[rx] == rk[ry] && rx != ry)
{
++rk[ry];
}
}
int main()
{
cin >> n >> m >> p;
for (int i = 1; i <= n; ++i)//初始化
{
a[i] = i;
rk[i] = 1;
}
for (int i = 1; i <= m; ++i)//输入一个关系就合并一次
{
cin >> m1 >> m2;
merge(m1, m2);
}
for (int i = 1; i <= p; ++i)
{
cin >> p1 >> p2;
if (find(p1) == find(p2))//如果两人属于同一个集合,则为亲戚
{
cout << "Yes" << endl;
}
else//反之
{
cout << "No" << endl;
}
}
return 0;
}
B.P3853 [TJOI2007]路标设置
思路:暑假集训的题目,求最大距离的最小值,直接二分
AC代码:
#include<bits/stdc++.h>
using namespace std;
int l, n, k, a[100005];
int check(int mid) {
int cnt = 0;
for (int i = 1; i < n; i++) {
cnt += ((a[i] - a[i - 1]) / mid);
if ((a[i] - a[i - 1]) % mid == 0) cnt--;
}
if (cnt <= k) return 1;
else return 0;
}
int main() {
cin >> l >> n >> k;
for (int i = 0; i < n; i++) cin >> a[i];
int left = 1, right = l;
while (left < right) {
int mid = (left + right) >> 1;
if (check(mid)) right = mid;
else left = mid+1;
}
cout << left;
return 0;
}
C.芝士原子
思路:模拟
AC代码:
#include<iostream>
using namespace std;
int t, n;
int a[] = { 2,6,10,14 };
string s = "spdf";
void solve(int x) {
for (int i = 1; x!=0; i++) {
for (int j = 1; j <= i; j++) {
if (x >= a[j - 1]) {
x -= a[j - 1];
cout << i << s[j - 1] << a[j - 1] << " ";
}
else {
cout << i << s[j - 1] << x << endl;
return;
}
}
}
}
int main() {
cin >> t;
while (t--) {
cin >> n;
solve(n);
}
return 0;
}
D.[ABC006A] 世界のFizzBuzz
AC代码:
if(!(n%3)){
cout<<"YES"<<endl;
return 0;
}
while(x>0){
x=y%10;
y=y/10;
if(x==3) z=true;
}
if(!z) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;