题目来源:https://codeforces.com/gym/104417
写在前面
这是我们ICPC训练赛的第一场,打的很一般(打的很菜),毕竟是刚开始的第一天,打的一般还可以接受,想着明天的训练赛一定要打好-------
回归正题
A - Orders
题意
给你n个订单,每个订单包含最终截止时间和所需要的产品,每天可以生产k个产品,请问工厂是否能完成所有订单
思路
签到题,一道简单的贪心模拟,只要将每个订单的截止时间进行升序排序,然后判断工厂生产的产品是否满足订单要求即可
编程
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int>
using namespace std;
const int N=1e6+5;
struct node{
int a,b;
};
node s[105];
bool cmp(node x,node y){
return x.a<y.a;
}
void solve(){
int n,k;
cin >>n >> k;
for(int i=0;i<n;++i){
cin >> s[i].a >> s[i].b;
}
sort(s,s+n,cmp);
int sum=0;
int flag=1;
for(int i=0;i<n;++i){
if(i==0) sum+=s[i].a*k;
else{
sum+=(s[i].a-s[i-1].a)*k;
}
sum-=s[i].b;
//cout << sum << " ";
if(sum<0){
flag=0;
break;
}
}
if(flag){
cout << "Yes" << endl;
}
else cout << "No" << endl;
return ;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t=1;
cin >> t;
while(t--) solve();
return 0;
}
I - Three Dice
题意
骰子红面包含1和4,黑面包含2,3,5,6,一次性投出3个骰子,判断输入的两个数是否能同时出现
思路
签到题,由于就3个骰子,所以全排列即可解出所有可能
编程
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int>
using namespace std;
const int N=100;
vector<int> v1[N],v2[N];
void solve(){
int a,b;
cin >> a >> b;
if(a==0){
if(b>=6&&b<=18){
cout << "Yes" << endl;
}
else cout << "No" << endl;
return ;
}
if(a==1||a==4){
if(b>=4&&b<=12){
cout << "Yes" << endl;
}
else cout << "No" << endl;
return ;
}
else if(a==2||a==5||a==8){
if(b==2||b==3||b==5||b==6){
cout << "Yes" << endl;
}
else cout << "No" << endl;
return ;
}
else if(a==3||a==6||a==9||a==12){
if(b==0) cout << "Yes" << endl;
else cout << "No" << endl;
return ;
}
else cout << "No" << endl;
return ;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t=1;
//cin >> t;
while(t--) solve();
return 0;
}
G - Matching
题意
给出一个序列,当i - j = a i a_i ai- a j a_j aj时,可以将i和j连接起来,那么它的权值为 a i a_i ai+ a j a_j aj,求这个序列最大的权值
思路
贪心+标记,由公式我们可以推出i - a i a_i ai=j - a j a_j aj,因此我们可以用map来存i-x(x为这个序列的数),然后遍历map,将每个标记的位置中最大的两个数进行相加即可,若小于0则不进行相加操作
编程
#include<bits/stdc++.h>
#define int long long
#define endl "\n"
#define fi first
#define se second
#define PII pair<int,int>
using namespace std;
const int N=5e5+5;
void solve(){
map<int,priority_queue<int>> m;//map存入最大堆
int n;cin >> n;
int ans=0;
for(int i=1;i<=n;++i){
int x;cin >> x;
m[i-x].push(x);
}
for(auto i : m){
priority_queue<int> q=i.se;
while(q.size()>=2){//若大于等于2每次取前两个数
int a=q.top();q.pop();
int b=q.top();q.pop();
if(a+b>0) ans+=a+b;
}
}
cout << ans << endl;
return ;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t=1;
cin >> t;
while(t--) solve();
return 0;
}
D - Fast and Fat
详细见博客
https://blog.csdn.net/wh233z/article/details/139244348?spm=1001.2014.3001.5501
总结
在这次训练赛中,A题和I题这两道签到题过的速度还行,G题卡了有点久,主要是那个公式转换想了半天·······,我也不知道我们队当时咋想的,就是没想到把那个公式变一下,赛时突然队友把这个公式颠倒了一下,就有了思路,我很快就用map存最大堆的算法将它实现了出来。至于那D题赛时没写出来······,主要还是当时没看出那是一道二分题,第二天的训练赛也是······,我发现我们队做二分的题目很薄弱,可能是当时只刷了简单的二分答案,至于稍微需要动点脑子的二分就写不出来了,赛后我也补了几道二分题,将这薄弱的算法补了一下,为下次做准备