题目链接:https://codeforces.com/contest/1294
A. Collecting Coins
题意:三姐妹分别有a,b,c个硬币,先让你把n个硬币分给三姐妹,使得她们的硬币数相同,如果能实现输出YES,否则输出NO。
思路:此题应注意是三姐妹接受硬币(可以为0),但是不能减少原有硬币数。
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF=0x3f3f3f3f;
const int MAXN=1e5+5;
int main()
{
int t; cin >> t;
while(t -- ){
int a, b, c, n;
cin >> a >> b >> c >> n;
if(a < b) {int t = a; a = b; b = t;}
if(a < c) {int t = a; a = c; c = t;}
if(b < c) {int t = b; b = c; c = t;}
//先让a,b,c都变成max(a, b, c)
int x = 2 * a - b - c;
if(n >= x && (n - x) % 3 == 0)
cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
B. Collecting Packages
题意:机器人要在坐标图上手机n个包裹,但是它只能向上移动(‘U’)和向右移动(‘R’)。换句话说,机器人可以一步移动从点(x,y)到点(x + 1,y)或点(x,y + 1)。机器人想以最少的步数手机完n个包裹,如果可行输出YES并输出字典序最小的路径,否则输出NO。
思路:显然我们可以定义结构体并进行排序(先满足横坐标升序,再满足纵坐标升序),然后就是遍历找到答案啦。
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF=0x3f3f3f3f;
const int N = 1e5+5;
struct node{
int x,y;
}s[N];
bool cmp(node a, node b)
{
if(a.x < b. x) return 1;
else if(a.x == b. x){
if(a.y < b.y) return 1;
else return 0;
}
else return 0;
}
int main()
{
int t;
cin >> t;
while(t -- ){
int n, vis = 0;
string ans;
cin >> n;
for(int i = 1; i <= n; i ++ )
cin >> s[i].x >> s[i].y;
sort(s + 1, s + n + 1, cmp);
for(int j = 1; j <= s[1].x - 0; j ++ )
ans += 'R';
for(int j = 1; j <= s[1].y - 0; j ++ )
ans += 'U';
for(int i = 2; i <= n; i ++ ){
if(s[i].x == s[i-1].x){
if(s[i].y > s[i - 1].y){
for(int j = 1; j <= s[i].y - s[i - 1].y; j ++ )
ans += 'U';
}
else{
cout << "NO" << endl;
vis = 1;
break;
}
}
if(s[i].y == s[i - 1].y){
if(s[i].x > s[i - 1].x){
for(int j = 1; j <= s[i].x - s[i - 1].x; j ++ )
ans +='R';
}
else{
cout << "NO" << endl;
vis = 1;
break;
}
}
if(s[i].x > s[i - 1]. x){
if(s[i].y > s[i - 1].y){
for(int j = 1; j <= s[i].x - s[i - 1].x; j ++ )
ans += 'R';
for(int j = 1; j <= s[i].y - s[i - 1].y; j ++ )
ans += 'U';
}
else if(s[i].y == s[i - 1].y) ;
else{
cout << "NO" << endl;
vis = 1;
break;
}
}
}
if(!vis) cout << "YES" <<endl << ans << endl;
ans.clear();
}
return 0;
}
C. Product of Three Numbers
题意:您会得到一个整数n。 找出三个不同的整数a,b,c使得2≤a,b,c和a⋅b⋅c= n输出YES和a b c,否则输出NO。
思路:其实相当于找到n的两个因子a和y,再找到y的两个因子b和c,使得a * b * c = n(且a,b,c互不相同);首先得判断n和y是否能得到两个不同得因子相乘等于自身,再进行处理(每次遍历到二次跟就好)。
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<=n;i++)
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5+5;
int v[N];
ll cmp(ll x)
{
ll y = sqrt(x);
for(ll i = 2;i <= y;i++)
if(x % i == 0 && !v[i])
return i;
return 0;
}
int main()
{
int t; cin >> t;
while(t--){
memset(v,0,sizeof(v));
ll a[5], n; cin >> n;
if(!cmp(n)){
cout << "NO" << endl;
continue;
}
else{
ll p = cmp(n);
a[0] = p;
v[p] = 1;
n /= p;
}
if(!cmp(n)){
cout << "NO" << endl;
continue;
}
else{
ll p = cmp(n);
a[1] = p;
v[p] = 1;
n /= p;
a[2] = n;
sort(a,a+3);
if(a[0] != a[1] && a[0] != a[2] && a[1] != a[2])
cout << "YES" << endl << a[0] << " " << a[1] << " " << a[2] << endl;
else cout << "NO" << endl;
}
}
}
D. MEX maximizing
题意:刚开始有一个空集合,会往里添加q次数,每次加一个值,而且你可以让这个数任意加减x若干次,每次添加后就查询当前最小的不属于这个集合的非负整数是什么。尽可能让这个最小的不属于这个数列的非负整数最大。
**思路:**由于每次添加的数t都可以加减任意次的x,故我们只需记录t%x,用num[i]表示i的个数,用res来查询是否可以满足要求,如果num[res%x]不为0,说明之前有一个没发挥作用的t可以用来顶替该位置上的res,说嘛现在的res就不是答案。
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int N = 4e5 + 5;
int num[N];
int main()
{
int q, x;
cin >> q >> x;
int res = 0;
while (q -- ){
int t;
cin >> t;
num[t % x] ++ ;
while (num[res % x]){
num[res % x] -- ;
res ++ ;
}
cout << res << endl;
}
return 0;
}