我是靠谱客的博主 年轻小笼包,最近开发中收集的这篇文章主要介绍codeforces 1380 总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

A
给一串数,找是否有i<j<k,ai<aj,aj>ak

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1005];
int main()
{
int t;
scanf("%d",&t);
int n;
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int p[4]={0};
int jud=0;
int flag=0;
for(int i=2;i<=n-1;i++)
{
p[2]=i;
jud=0;
flag=0;
for(int j=i-1;j>=1;j--)
{
if(a[j]<a[p[2]])
{
p[1]=j;
jud=true;
break;
}
}
if(jud)
{
for(int j=i+1;j<=n;j++)
{
if(a[p[2]]>a[j])
{
p[3]=j;
flag=1;
break;
}
}
}
if(flag) break;
}
if(flag)
{
printf("YESn");
printf("%d %d %d",p[1],p[2],p[3]);
printf("n");
}
else printf("NOn");
}
return 0;
}

B
剪子包袱锤,给出一串顺序,问另一串顺序怎样才能使赢得平均场数最多,(每个位置都轮换一遍)。
思路:
每个位置上的东西都要和上一串的每一个位置比,那么干脆就这样,找出能获胜最多的那个东西,然后这一串全是他。

#include <iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<utility>
using namespace std;
char ch[200005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
pair<int,char>d[4];
d[1].second='P';
d[2].second='S';
d[3].second='R';
scanf("%s",ch+1);
int len=strlen(ch+1);
d[1].first=0,d[2].first=0,d[3].first=0;
for(int i=1;i<=len;i++)
{
if(ch[i]=='P') d[2].first++;
else if(ch[i]=='S') d[3].first++;
else d[1].first++;
}
sort(d+1,d+4);
for(int i=1;i<=len;i++)
printf("%c",d[3].second);
printf("n");
}
return 0;
}

C
n个数分组,要求组内数的个数乘以组内最小的数要大于等于x,问最多分多少组?
思路:大的尽量单独或者少量几个数为一组,小的就扎堆为一组就好。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll a[100005];
bool cmp(ll p1,ll p2)
{
return p1>p2;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll n;
ll x;
scanf("%lld%lld",&n,&x);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
sort(a+1,a+1+n,cmp);
ll cnt=0;
ll num=0;
ll pos=0;
while(1)
{
pos++;
cnt=0;
while(1)
{
cnt++;
if(cnt*a[pos+cnt-1]>=x)
{
//printf("%lldn",a[pos+cnt-1]);
num++;
pos=pos+cnt-1;
//printf("%lldn",pos);
// printf("%lldn",cnt);
break;
}
if(pos+cnt-1>=n) break;
}
if(pos>=n) break;
if(pos+cnt-1>=n) break;
}
printf("%lldn",num);
}
return 0;
}

D
给一组数,有两种操作,一种是选连续的k个数,删掉他们,花费为x,一种是选连续的两个数,删掉小的一个,花费为y,问能否通过这两种操作得到指定的序列?
思路:连续这个条件很重要,如果不是连续的,那就糟了。由于对是连续的数操作,那么就定义两个指针,一个指向原有序列,一个指向给定序列,找出需要删掉的区间(两边夹着的就是),然后判断区间能否被删掉,若能,在找最小值。

但是,这题的官方题解有漏洞,官方题解在减掉余数后没有判断区间长度是否为零直接进行找小值的步骤,若为零的话,则有可能有错误出现。加上这个条件就好。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5+5;
int n, m;
long long x, k, y;
int a[N];
int b[N];
ll res=0;
bool jud(int l, int r)
{
if (l > r) return true;
bool flag = false;
int mx = *max_element(a + l, a + r + 1);
int len = r - l + 1;
if (l - 1 >= 0 && a[l - 1] > mx) flag = true;
else if (r + 1 < n && a[r + 1] > mx) flag = true;
if (len < k && !flag) return false;
int need = len % k;
res += need * y;
len -= need;
if(len==0) return true;
if (y * k >= x)
{
res += len / k * x;
}
else if(flag)
{
res += len * y;
}
else
{
res += (len - k) * y + x;
}
return true;
}
int main()
{
scanf("%d %d", &n, &m);
scanf("%lld %lld %lld", &x, &k, &y);
for (int i = 0; i < n; ++i) scanf("%d", a + i);
for (int i = 0; i < m; ++i) scanf("%d", b + i);
int lst = -1, posa = 0, posb = 0;
while (posb < m)
{
while(posa < n && a[posa] != b[posb]) ++posa;
if (posa == n)
{
puts("-1");
return 0;
}
if (!jud(lst + 1, posa - 1))
{
puts("-1");
return 0;
}
lst = posa;
++posb;
}
if (!jud(lst + 1, n - 1))
{
puts("-1");
return 0;
}
printf("%lldn", res);
return 0;
}

E
这题,题目看了一晚上,还是没能搞懂题目是啥意思,大体意思倒是和汉诺塔挺像的,最后到底查询的是哪个difficulty的值还没搞清楚,这题,理解题意就能搞死一大批人吧。哎,在理解理解。

最后

以上就是年轻小笼包为你收集整理的codeforces 1380 总结的全部内容,希望文章能够帮你解决codeforces 1380 总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部