前言
补题
总结
这一周的作息不好,导致很多东西没有来得及学。为了调整状态换了个环境 ,新的一周会努力的。
基于这一周的比赛发现一些问题:
数据量大的数据不会处理
思考问题的方式很奇怪,容易想的复杂或思维一直在绕圈,其实也是因为做(补)题不够多
B.Streamer night
题意:有很多节目,告诉你总时间和每个节目的开始结束时间,求时间之内最多看完多少节目。
思路:用结构体收集所有数据并排序,然后贪心地选取节目。
#include
using namespace std;
#define int long long
struct node{
int l,r;
}a[200005];
bool cmp(node a,node b){
return a.r<b.r;
}
void solve(){
int n,k;cin>>n>>k;
for(int i=1;i<=k;i++){
cin>>a[i].l>>a[i].r;
}
sort(a+1,a+1+k,cmp);
int count=1,last=a[1].r;
for(int i=2;i<=k;i++){
if(a[i].l>=last){
last=a[i].r;
count++;
}else continue;
}
cout<<count;
}
signed main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;t=1;
while(t--){
solve();
}
return 0;
}
小结:在第一次补的时候,是直接将这一次的l与上一个r比较,这样有可能会比较到你不看的节目;且在排序的时候只比较r就可以了,因为开始看节目的时间是固定的,结束的越早说明时间越短。这也是我在赛时没有想到的。
E.Football tournament
题意:有n个各有实力的球队,任取两个队伍打比赛直到每个队伍都交手过除自己以外的所有队伍(双向,A打过B也相当于B打过A)实力强于对方得3分,相等得2分,弱于对方不得分,你作为教练训练一次可以增强任意一支队伍一点实力,问至少训练多少次可以达到所有队伍的总得分最大?
思路:只要完全递增就能使总得分最大,例如1 2 2 3 3 4,变成 1 2 3 4 5 6就是得分最大的情况。
#include
using namespace std;
#define int long long
void solve(){
int n;
cin>>n;
vector<int>a(n,0);
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a.begin(),a.end());
int count=0;
for(int i=1;i<n;i++){
if(a[i]<=a[i-1]){
count+=a[i-1]-a[i]+1;
a[i]=a[i-1]+1;
}
}
cout<<count;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;t=1;
while(t--){
solve();
}
return 0;
}
小结:同样在第一次补的时候,是只加一然后再次排序,到第41个测试样例的时候TLE了…但是列举了几个例子之后发现确实实现完全递增就是唯一的方向之后就只需要每次直接比前一个大1就能实现完全递增了。
F.Astronomy
题意:非常大的数做加法。
思路:如果需要的话先补零使它们对齐,然后从最后一位~~(也就是个位)~~将单个的字符常量转换成数字相加再加上上一位要进位的数字(如果有的话)作为在这一位两个数字相加的总和;这个总和除10就是要进位的数字,对10取余就是求和后的这一位应该有的数字,然后转换成字符常量推入储存答案的字符串;最后翻转一下再输出。
#include
using namespace std;
#define int long long
void solve(){
string ab,bc;
cin>>ab>>bc;
int count1=ab.length(),count2=bc.length();
int maxx=max(count1,count2);
if(maxx>count2){
bc.insert(0,maxx-count2,'0');
}else if(maxx>count1){
ab.insert(0,maxx-count1,'0');
}
string ans;int temp=0;
for(int i=maxx-1;i>=0;i--){
int s1=ab[i]-'0';
int s2=bc[i]-'0';
int sum=s1+s2+temp;
temp=sum/10;
ans.push_back((sum%10)+'0');
}
if(temp==1){
ans.push_back(temp+'0');
}
reverse(ans.begin(),ans.end());
cout<<ans;
}
signed main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;t=1;
while(t--){
solve();
}
return 0;
}
小结:其实我赛时做出来了但是我感觉方法不错(比较容易想)所以记录下^^
C.Negatives and Positives
题意:有n个数,你可以将ai和ai+1同时变成相反数任意次,求这些数的最大和。
思路:如果负数有偶数个,最后总能变成全正;如果有奇数个,最后总能只让绝对值最小的是负数;
#include
using namespace std;
#define endl '\n'
#define int long long
void solve(){
int n;cin>>n;
vector<int>a(n,0);
int fcount=0,zans=0,jmin=INT_MAX;
for(int i=0;i<n;i++){
cin>>a[i];
if(fabs(a[i])<=jmin) jmin=fabs(a[i]);
zans+=fabs(a[i]);
if(a[i]<0) fcount++;
}
if(fcount%2==0){
cout<<zans<<endl;
}else cout<<zans-jmin*2<<endl;
}
signed main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--){
solve();
}
return 0;
}
小结:当时的格局小了,一直在考虑ai和ai+1的9种情况而且当时想的是直接遍历a0到an-1,但这样做不一定就是最优解。
H.Grab the Candies
题意:有n袋,A小孩拿偶数个的那袋,另一个拿奇数的那袋,问能否给这几袋糖排个序使得A小孩的糖任意时刻都大于另一个小孩?
思路:偶数和大于奇数和就能做到,因为只要先取完所有偶数袋就可以一直比另一个小孩多。
#include
using namespace std;
#define endl '\n'
#define int long long
void solve(){
int n;
cin>>n;
vector<int>a(n,0);int jcount=0,ocount=0;
for(int i=0;i<n;i++){
cin>>a[i];
if(a[i]%2==0){
ocount+=a[i];
}else jcount+=a[i];
}
if(ocount>jcount){
cout<<"YES\n";
}else cout<<"NO\n";
}
signed main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--){
solve();
}
return 0;
}
小结:没做出来是因为比赛到后期时间不足了(昨晚熬夜起晚了…)下一周我将早睡/.
这一周相对于第一周有一定进步,对于STL的使用更加熟练而且赛时坐得住了,也改掉了一些不好的习惯。下周继续填之前的坑,同时争取多打各种比赛,换了新环境之后会全力以赴的。计划先复习一下DP及BFS、DFS,同时复习一下C++,准备一下三月末的计算机考试。