https://codeforces.com/contest/1244/problem/C
C:
题目大意:找X,Y,Z满足上式。
题目思路:
明显Z是补n的作用,那么只要让x+y尽量的小就可以了,w>d那么就尽量让x多一点,y少一点。
枚举y [ 0 , w ) ,如果 y 大于w了,那么意思就是包含了大于w个d,那么为什么不分给 x 让y变小点呢。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ll n,p,w,d;
cin>>n>>p>>w>>d;
ll y;
for(int i=0;i<w;i++){
if( ( p-d*i )%w ==0){
y = i;break;
}
}
ll x = (p-d*y)/w;
ll z = n-x-y;
if(x<0||y<0||z<0){
cout<<-1<<endl;
}
else cout<<x<<" "<<y<<" "<<z<<endl;
}
D:
题目大意:给一棵树,要求相邻三个点颜色不同的最小花费。
很容易看出是一条链,那么端点颜色定了的话,全部的颜色就都确定了,只有六种情况,枚举一遍就行
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MAXN = 1e5+5;
vector<int>v[MAXN];
ll c[5][MAXN];
ll vis[MAXN];
ll col[MAXN],cou[MAXN];
struct node
{
ll co,id;
node(ll a,ll b){
co = a;id = b;
}
};
ll ret = 0;
ll idx;
void dfs(ll fa,ll x,ll now_c,ll a,ll b,ll C)
{
col[x] = now_c;
ll len = v[x].size();
for(ll i=0;i<len;i++){
ll to = v[x][i];
if(to == fa)continue;
if(now_c == a)
dfs(x,to,b,a,b,C);
if(now_c == b)
dfs(x,to,C,a,b,C);
if(now_c == C)
dfs(x,to,a,a,b,C);
}
}
int main()
{
ll n;
cin>>n;
for(ll i=1;i<=3;i++){
for(ll j=1;j<=n;j++){
cin>>c[i][j];
}
}
for(ll i=1;i<n;i++){
ll a,b;
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
bool f=1;
for(ll i=1;i<=n;i++){
if(v[i].size()>=3)f=0;
}
if(!f){
cout<<-1<<endl;
return 0;
}
ll ans = 1ll<<62;
idx = 0;
for(ll i=1;i<=n;i++){
ll len =v[i].size();
if(len == 1){
idx = i;
break;
}
}
ll bb[5];
bb[1] = 1; bb[2] = 2; bb[3] = 3;
do{
ll ret = 0;
dfs(0,idx,bb[1],bb[1],bb[2],bb[3]);
for(ll i=1;i<=n;i++){
ret += c[col[i]][i];
}
if(ans > ret){
ans = ret;
for(ll i=1;i<=n;i++){
cou[i] = col[i];
}
}
}while(next_permutation(bb+1,bb+4));
cout<<ans<<endl;
for(ll i=1;i<=n;i++){
cout<<cou[i]<<" ";
}
cout<<endl;
}
E: E. Minimizing Difference
https://codeforces.com/contest/1244/problem/E
题目大意:
给一个数组,k次操作,每次找一个数字+1或者-1,问最小差距可以减小到多少。
题目思路:
和2019某场网络赛的签到很相似,那个是取一个还要放回来,这个取走放回是单独的,比那个简单一点。
首先排序,然后肯定是高的往下靠拢,低的往上靠拢,那么选择下边的还是上边的呢,这取决与谁使得总差距减小的花费的大小,定义两根指针,一个idx1从前往后跳,一个idx2从后往前跳,意思就是当前前边的被填平了多少和后边被填平了多少。
直接模拟就行了,知道k<0或者,idx>=idx2
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll MAXN = 1e5+5;
ll a[MAXN];
ll n,k;
int main()
{
cin>>n>>k;
for(ll i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
ll idx1=1,idx2=n;
for(ll i=2;i<=n;i++){
if(a[i] == a[1]){
idx1 = i;
}
else break;
}
for(ll i=n-1;i>=1;i--){
if(a[i] == a[n]){
idx2 = i;
}
else break;
}
ll dis = a[n] - a[1];
ll sum = 0;
while(idx1<idx2)
{
if(idx1 > n-idx2+1){
ll now_dis = a[idx2]-a[idx2-1];
ll Max = (n-idx2+1)*now_dis;
if(k >= Max){
ll x = lower_bound(a+1,a+1+n,a[idx2-1])-a;
idx2 = x;
k -= Max;
dis -= now_dis;
}
else{
ll f = k/(n-idx2+1);
k = 0;
dis -= f;
}
}
else{
ll now_dis = a[idx1+1]-a[idx1];
ll Max = (idx1)*now_dis;
if(k >= Max){
ll x = upper_bound(a+1,a+1+n,a[idx1+1])-a-1;
idx1 = x;
k -= Max;
dis -= now_dis;
}
else{
ll f = k/(idx1);
k = 0;
dis -=f;
}
}
if(k<=0)break;
}
if(k){
cout<<0<<endl;
}
else cout<<dis<<endl;
}