Codeforces Round 1003 (Div. 4)

preface

前五道还是很好想,第三和第四道代码不好写(可能是很久没写这种题了),第五道可能熬夜脑壳炸了

A

将末尾的us换成i

B

如果两个字符相同且相邻,那么就可以改变前一个,抹除后一个

  • 很容易想到从某个位置有两个相同的之后,之后的都可以被抹除
  • 但很快你也能想到,抹除最后一个时,前一个可以和前前一个相同

所以只要有相同且相邻的,那么只会留下一个,否则只剩下全部

C1

对于该题b[i]只有一个,所以对于每一个a[i],要么变成a[i],要么变成b[1]-a[i]

很容易想到贪心,尽可能的使每一个a[i]变小,且同时仍然大于a[i-1]

点击查看代码
#include<bits/stdc++.h>

using namespace std;

int t;
const int maxn=2e5+10;
int a[maxn],b[maxn]; 
int n,m;

void solve(){
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>a[i];
	for(int i=1;i<=m;++i) cin>>b[i];
	sort(b+1,b+1+m);	
	a[1]=min(a[1],b[1]-a[1]); 
	for(int i=2;i<=n;++i){
		if(min(a[i],b[1]-a[i])<a[i-1])
			a[i]=max(a[i],b[1]-a[i]);
		else a[i]=min(a[i],b[1]-a[i]);
		if(a[i]<a[i-1]){
			puts("no");return ; 
		} 
	} 
	puts("yes");

}
int main(){
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
} 

C2

该题与上一题唯一不同的点就在于,b[i]可选的数量更多,但是贪心的本质依然没变

我们看到,任选b[i],而且注意到这题与选择的b[i]的大小有明显的关系

那么排序+二分就是很自然的选择

点击查看代码
#include<bits/stdc++.h>

using namespace std;
#define int long long 
int t;
const int maxn=2e5+10;
int a[maxn],b[maxn]; 
int n,m;

bool find(int p){
	int l=1,r=m;
	while(l<=r){
		int mid=(l+r)>>1;
		if(b[mid]-a[p]>=a[p-1]) r=mid-1;
		else l=mid+1; 
	}
	if(l<=m){
		if(a[p]>=a[p-1])
			a[p]=min(a[p],b[l]-a[p]);
		else a[p]=b[l]-a[p];
	}  
	
	if(a[p]<a[p-1]){
		return false;
	}
	return 1;

}
void solve(){
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>a[i];
	for(int i=1;i<=m;++i){
		cin>>b[i];
	}
	a[0]=-1e15; 
	sort(b+1,b+1+m);	
	for(int i=1;i<=n;++i){ 
		if(find(i)) continue;
		else {
			puts("No");
			return ;
		}
		
	}
	puts("yes");

	return ; 
}
signed main(){
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
} 
#D

这题很经典,类似于排队取水

很容易发现,越在前面的数,累计到答案的次数更多,而我们只能改变一排数与一排数之间的关系

所以一排数和更大的放在前面,如果一排的数和一样大,那么就根据头一个数决定,如果头一个数也相同就依次比较(貌似这题数据水了,不用考虑后面的情况

点击查看代码
#include<bits/stdc++.h>

using namespace std;
using ll = long long;

struct node {
    ll sum = 0;
    ll maxnum; 
    int p;
} a[200010];

bool cmp(node x, node y) {
    if(x.sum!=y.sum)return x.sum > y.sum;
    return x.maxnum>y.maxnum; 
}
vector<vector<ll>> mp;
vector<ll> s;
void solve() {
    int n, m;
    cin>>n>>m;
    mp.clear();
    s.clear();
    for (int i =0;i<n;++i) { 
        vector<ll> row;
        ll cnt = 0;
        for (int j=0;j<m;++j) { 
            ll x; 
            cin>>x;
            cnt+=x;
            a[i].maxnum=max(a[i].maxnum,x);
            row.push_back(x);
        }
        mp.push_back(row); 
        a[i].sum=cnt;
        a[i].p=i;
	}
    ll ans = 0;
    sort(a,a+n,cmp); 
    for (int i=0;i<n;++i) {
        for (int j=0;j<m;++j) {
            s.push_back(mp[a[i].p][j]);
        }
    }

    int len=s.size();
    for(int i=0;i<len;++i) {
        ans+=s[i]*(len-i);
    }

    cout<<ans<< endl;
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

本文作者:归游

本文链接:https://www.cnblogs.com/guiyou/p/18708975

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   归游  阅读(46)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起