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;
}
这题很经典,类似于排队取水
很容易发现,越在前面的数,累计到答案的次数更多,而我们只能改变一排数与一排数之间的关系
所以一排数和更大的放在前面,如果一排的数和一样大,那么就根据头一个数决定,如果头一个数也相同就依次比较(貌似这题数据水了,不用考虑后面的情况
点击查看代码
#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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步