Codeforces Round #615 (Div. 3)
题库链接
https://codeforces.com/contest/1294
A. Collecting Coins
有a,b,c,n个硬币,把n分配下去,使得a=b=c
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin(T);
while(T--)
{
int a,b,c,n;
cin>>a>>b>>c>>n;
if(a < b) swap(a,b);
if(a < c) swap(a,c);
int sum = a+b+c+n;
if(sum%3 == 0 && sum/3 >= a)
{
puts("YES");
}
else puts("NO");
}
return 0;
}
B. Collecting Packages
有n个点,机器人一开始位于(0,0),只能向上或者向右走,问能不能走遍n个点,并且输出路径,要求字典序最小
也就是向右上走,模拟一下就好了
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 1110;
const int M = 1e9+7;
int n,m,k,t;
struct node
{
int x,y;
}a[maxn];
bool cmp(node a,node b)
{
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin(T);
while(T--)
{
cin(n);
for(int i = 0; i < n; i++)
{
cin>>a[i].x>>a[i].y;
}
sort(a,a+n,cmp);
bool flag = true;
for(int i = 1; i < n && flag; i++)
{
if(a[i].x < a[i-1].x || a[i].y < a[i-1].y) flag = false;
}
if(flag)
{
puts("YES");
int x = 0, y = 0;
for(int i = 0; i < n; i++)
{
if(a[i].x > x)
{
for(int j = x; j < a[i].x; j++) putchar('R');
x = a[i].x;
}
if(a[i].y > y)
{
for(int j = y; j < a[i].y; j++) putchar('U');
y = a[i].y;
}
}
puts("");
}
else puts("NO");
}
return 0;
}
C. Product of Three Numbers
三个数的乘积,\(2 \le a, b, c\)并且\(a \cdot b \cdot c = n\)
枚举,O(sqrt(n))
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,t;
int ans[4];
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin(T);
while(T--)
{
cin(n);
int res = 0;
int sx = sqrt(n);
for(int i = 2; i <= sx; i++)
{
if(res == 3 || i > n) break;
if(res == 2)
{
ans[res++] = n;
break;
}
if(n%i == 0)
{
n /= i;
ans[res++] = i;
}
}
if(res == 3)
{
puts("YES");
cout<<ans[0]<<' '<<ans[1]<<' '<<ans[2]<<endl;
}
else puts("NO");
}
return 0;
}
D. MEX maximizing
mex最大化,每次输入一个数,先从小的填,模拟
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 501110;
const int M = 1e9+7;
int n,m,k,t;
int a[maxn];
map<int,bool> mp;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int q,x,y;
cin>>q>>x;
int now = 0;
mem(a,-1);
for(int i = 1; i <= q; i++)
{
cin>>y;
int temp = y%x;
if(a[temp] == -1)
{
a[temp] = temp;
mp[temp] = 1;
}
else
{
a[temp] += x;
mp[a[temp]] = 1;
}
while(mp[now])
{
now++;
}
cout<<now<<endl;
}
return 0;
}
E. Obtain a Permutation
给定一个矩阵,有两种操作,将一个数变成任意数,将列往上移,求最小操作数,使得最终矩阵为(1,2,3...)
显然列和列之间是独立的,对于每一列,求出所需的最小操作数
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,t;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
cin>>n>>m;
int a[n][m];
int cnt[n][m];
ll ans = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
cin>>a[i][j];
cnt[i][j] = 0;
}
}
for(int j = 0; j < m; j++)
{
for(int i = 0; i < n; i++)
{
if(a[i][j]%m == (j+1)%m && a[i][j] <= n*m) //如果这个元素属于这一列
{
int t = a[i][j] - j - 1;
t /= m; //这个元素的正确位置应该是第t行
cnt[(i-t+n)%n][j]++; //现在在第i行,如果移动i-t行就到了正确位置
}
}
int res = inf;
for(int i = 0; i < n; i++)
{
res = min(res,i+(n-cnt[i][j])); //i+(n-cnt[i][j]),移动i行,有(n-cnt[i][j])个元素是错误的
//所以总的操作数是i+(n-cnt[i][j])
}
ans += res;
}
cout<<ans<<endl;
return 0;
}
F. Three Paths on a Tree
在一棵树上找三个点,使得他们的路径总的经过的边最多
先利用树的直径求出两个点,第三个点利用前两个点的路径上的点,多源bfs求出
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 501110;
const int M = 1e9+7;
int head[maxn],to[maxn],Next[maxn],cnt = 2;
void add(int u,int v)
{
to[cnt] = v;Next[cnt] = head[u];head[u] = cnt;cnt++;
}
int d[maxn],p,ans;
int fa[maxn];
void dfs(int u,int pre)
{
fa[u] = pre;
d[u] = d[pre]+1;
if(ans < d[u])
{
p = u;
ans = d[u];
}
for(int i = head[u]; i ; i = Next[i])
{
int v = to[i];
if(v == pre) continue;
dfs(v,u);
}
}
void find(int x)
{
ans = 0;
dfs(x,0);
}
struct node
{
int a,b;
node(int x,int y)
{
a = x;b = y;
}
};
bool vis[maxn];
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int n,a,b;
cin(n);
for(int i = 1,x,y; i < n; i++)
{
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
find(1);
a = p; //第一个点
ans = 0;
find(a);
b = p; //第二个点
queue<node> q;
int x = b;
while(x)
{
q.push(node(x,0));
vis[x] = 1;
x = fa[x];
}
int u = 0,dis = 0;
while(!q.empty()) //bfs
{
u = q.front().a;
dis = q.front().b;
q.pop();
for(int i = head[u]; i ; i = Next[i])
{
int v = to[i];
if(vis[v]) continue;
vis[v] = 1;
q.push(node(v,dis+1));
}
}
if(u == a || u == b)
{
for(int i = 1; i <= n; i++)
{
if(i != a && i != b)
{
u = i;
break;
}
}
}
cout<<ans-1+dis<<endl;
cout<<a<<' '<<b<<' '<<u<<endl;
return 0;
}