2022ccpc女生赛+补题

补题地址

A. 减肥计划

思路:

当k>=(n-1)时,满足条件的数一定是最大数,输出最大数位置即可;

否则,需要从前遍历到最大数位置,若在最大数出现之前出现能满足连续获胜k次的数则为该数,否则就是最大数。

代码:

#include
#define ll long long
const int maxn=1e6+10;
using namespace std;
int n,k;
ll maxx=-1,mt;
int a[maxn]={0};
int main()
{
  cin>>n>>k;
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&a[i]);
    if(a[i]>maxx)maxx=a[i],mt=i;
  }
  if(n-1<=k)printf("%d\n",mt);
  else
  {
    int temp=-1,ma=a[1],t=1,cnt=0;
    for(int i=2;i<=mt;i++)
    {
      if(a[i]>ma){cnt=1,ma=a[i],t=i;}
      else cnt++;
      if(cnt>=k){temp=1;break;}
    }
    if(temp==1)printf("%d\n",t);
    else printf("%d\n",mt);
  }
  //system("pause");
  return 0;
}

C. 测量学

思路:

先对角度进行预处理,大于pi则取2pi-角度。对每条路进行比较即可。

代码:

#include
#define ll long long
#define pi acos(-1)
using namespace std;
int n;
double R,r,du;
double ans=0x3f3f3f3f;
int main()
{
  //printf("%.40lf\n",pi);
  cin>>n>>R>>du;ans=2*R;
  if(du==0)ans=0;
  else if(du==pi)ans=2*R;
  else if(du>pi)du=(2*pi-du),ans=min(ans,du*R);
  else ans=min(ans,du*R);
  for(int i=1;i<=n;i++)
  {
    cin>>r;
    double res=2*(R-r)+du*r;
    ans=min(ans,res);
  }
  printf("%.6lf\n",ans);
  system("pause");
  return 0;
}

E. 睡觉

思路:

经过一段音乐之后清醒度有增加、减少和不变三种情况。

若清醒度减少,说明经过无限长时间清醒度会一直减少,因此在在无限长时间内一定会满足;

否则,我们可以特判,在一段音乐的中间是否存在一段满足or在一段音乐的尾部和第二段音乐的前部连接起来是否满足;

除此之外,还存在一种情况为当x==k,qie一段音乐后清醒度不变且中间不存在x>k;由于x一直<=k则在无限长时间内一定可以满足,特判即可。

代码:

#include
const int maxn=1e5+10;
using namespace std;
int x,t,k,n,d;
void solve()
{
  scanf("%d%d%d%d%d",&x,&t,&k,&n,&d);
  int a[maxn]={0};
  int cnt=0;
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&a[i]);
    if(a[i]<=d)cnt--;else cnt++;
  }
  if(cnt<0)printf("YES\n");
  else
  {
    int xx=x,tt=0,temp=-1;
    //查询中间是否有段音乐符合
    //同时记录最后一次大于k的位置
    int last=0;
    for(int i=1;i<=n;i++)
    {
      if(a[i]<=d)xx--;else xx++;
      if(xx<=k)
      {
        tt++;
        if(tt>=t){temp=1;}
      }
      else {last=max(last,i);tt=0;}
    }
    //查询一段音乐的尾部和前部组合是否符合
    //记录前部第一次大于k的位置-1
    int first=0;
    for(int i=1;i<=n;i++)
    {
      if(a[i]<=d)xx--;else xx++;
      if(xx<=k)first=max(first,i);
      else break;
    }
    if(n-last+first>=t)temp=1;
    if(last==0&&x==k&&cnt==0)temp=1;//特判x==k且整段音乐下来清醒度都不大于k的情况
    if(temp==1)printf("YES\n");
    else printf("NO\n");
  }
}
int main()
{
  int t;
  cin>>t;
  while(t--)solve();
  //system("pause");
  return 0;
}

G. 排队打卡

思路:

算是一道模拟题,首先要记得给日志时间排序(比赛的时候就忘了)

由于题目明确醒来时间不会等于日志记录的时间且一定有记录的时间大于醒来时间,因此只需要在第一个大于醒来时间的日志判断人数是否符合。

判断后在秒初始先结算下当前人数,注意判断人数为负的情况要置零。

加上当前日志时间排队人数后再比较最短排队时间,注意时间相等时选取靠后的时间段。

代码:

#include
#define ll long long
const int maxn=5e5+10;
using namespace std;
ll t,n,m,k;
ll sum=0,tlast=1,temp=-1,tt=-1;//temp标记符合日志,tt标记已判断过
ll mini,minitime=0x3f3f3f3f;
struct point
{
  ll ti,x;
}a[maxn];
bool cmp1(point x,point y)
{
  return x.tit&&tt==-1)
    {
      tt=1;
      sum-=k*(t-tlast);
      if(sum<0)sum=0;
      if(sum==n)temp=1;
      tlast=t;
    }
    sum-=(a[i].ti-tlast)*k;tlast=a[i].ti;
    if(sum<0)sum=0;
    sum+=a[i].x;
    //比较最短排队时间
    if(tt==1)        
    {
      ll tim;
      if((sum+1)/k*k!=(sum+1))tim=(sum+1)/k+1;
      else tim=(sum+1)/k;
      if(tim<=minitime)minitime=tim,mini=a[i].ti;
    }
  }
  if(temp!=1)cout<<"Wrong Record"<

(先占坑)

H. 提瓦特之旅

思路:

代码:

I. 宠物对战

思路:

代码:

你可能感兴趣的:(codeforces,ccpc,算法,c++,数据结构)