2018-2019赛季多校联合新生训练赛第三场(2018/12/8)补题题解

Posted baccano-acmer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-2019赛季多校联合新生训练赛第三场(2018/12/8)补题题解相关的知识,希望对你有一定的参考价值。

感慨

得复习回溯和dfs了。。。

A 变形虫(语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
map<int,int> num;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m;
  cin>>n>>m;
  for(int i=0;i<m;i++)
  cin>>num[i];
  for(int i=0;i<m;i++)
  if(num[i]==n)
  n+=num[i];
  cout<<n;
}

B 冬眠 (数学)

注意避免超时先找一下最后在周期内的哪一个位置

代码

#include <bits/stdc++.h>
using namespace std;
map<int,int> num;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m,t=0,sum=0,re=0;
  cin>>n>>m;
  for(int i=0;i<m;i++)
  cin>>num[i],re+=num[i];
  sum+=m*(n/re);
  n%=re;
  while(n>0)
  {
    n-=num[t];
    t++;
    t%=m;
    sum++;
  }
  cout<<sum;
}

C 进制转换 (语法基础)

我的思路是先化成十进制,再按照栈的思想化成各种进制。。。这估计也不是正解

代码

#include <bits/stdc++.h>
using namespace std;
map<int,int> sum;
stack <char> st;
int qb(int a,int b)
{
  int re=1;
  for(int i=0;i<b;i++)
  re*=a;
  return re;
}
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,sum=0;
  cin>>n;
  string a;
  cin>>a;
  int len=a.size();
  for(int i=0;i<len;i++)
  {
    if(a[i]==‘A‘)
    sum+=10*qb(n,len-i-1);
    else if(a[i]==‘B‘)
    sum+=11*qb(n,len-i-1);
    else if(a[i]==‘C‘)
    sum+=12*qb(n,len-i-1);
    else if(a[i]==‘D‘)
    sum+=13*qb(n,len-i-1);
    else if(a[i]==‘E‘)
    sum+=14*qb(n,len-i-1);
    else if(a[i]==‘F‘)
    sum+=15*qb(n,len-i-1);
    else
    sum+=(a[i]-‘0‘)*qb(n,len-i-1);
  }
  int m;
  cin>>m;
  while(sum)
  {
    int t=sum%m;
    char c;
    if(t==10)
    c=‘A‘;
    else if(t==11)
    c=‘B‘;
    else if(t==12)
    c=‘C‘;
    else if(t==12)
    c=‘C‘;
    else if(t==13)
    c=‘D‘;
    else if(t==14)
    c=‘E‘;
    else if(t==15)
    c=‘F‘;
    else if(t<10)
    c=char(t+‘0‘);
    sum/=m;
    st.push(c);
  }
  while(st.size())
  {
    cout<<st.top();
    st.pop();
  }
}

D 最大的数II (数学)

找一下递推式,判断一下条件即可

代码

#include <bits/stdc++.h>
using namespace std;
map<int,int> sum;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m,t=0,re=0;
  cin>>n;
  for(int i=1;i<=100000;i++)
  sum[i]=i+sum[i-1];
  for(int i=1;;i++)
  {
    if(sum[i]>n)
    {
      cout<<i-1;
      break;
    }
    else if(sum[i]==n)
    {
      cout<<i;
      break;
    }
  }
}

E 取数排列 (全排列)

打个全排列抽一下数即可

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
  /*ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);*/
  int n,m,sum=0;
  cin>>n>>m;
  for(int i=0;i<n;i++)
  bk[i]=i+1;
  do {
    sum++;
    if(sum==m)
    {
      for(int i=0;i<n;i++)
      {
        cout<<bk[i];
      }
      break;
    }
  } while(next_permutation(bk,bk+n));
}

F 懒羊羊找朋友 (结构体排序)

解法

首先要找距离

公式为:|xi-x|+|yi-y|

然后把所有的相同数的点的距离算出来之后,再按照他给的条件排个序输出即可

代码

#include <bits/stdc++.h>
using namespace std;
int mp[1000][1000];
struct node
{
  int x,y,dis;
}bk[1000000];
bool cmp(node a,node b)
{
  return a.dis==b.dis?a.x==b.x?a.y<b.y:a.x<b.x:a.dis<b.dis;
}
int main()
{
  /*ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);*/
  int n,m,x,y,p=0;
  cin>>n>>m>>x>>y;
  for(int i=1;i<=n;i++)
  for(int j=1;j<=m;j++)
  cin>>mp[i][j];
  for(int i=1;i<=n;i++)
  for(int j=1;j<=m;j++)
  if(mp[i][j]==mp[x][y])
  {
    if(i==x&&j==y)
    continue;
    bk[p].x=i,bk[p].y=j,bk[p++].dis=abs(i-x)+abs(j-y);
  }
  sort(bk,bk+p,cmp);
  cout<<bk[0].x<<" "<<bk[0].y;
}

G 求满足条件的数 (语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
int sum[100000];
int bk[100000];
char c[10000];
int main()
{
  /*ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);*/
  int n,tot=0;
  cin>>n;
  for(int i=69;i<=n;i++)
  {
    stringstream s;
    s<<i;
    string ss;
    s>>ss;
    int sum=0;
    for(int i=0;i<ss.size();i++)
    sum+=ss[i]-‘0‘;
    if(sum==15)
    printf("%6d",i),tot++;
    if(tot==8)
    printf("
"),tot=0;
  }
}

H 自然数无序拆分 (DFS)

回溯

I 大写字母的序列 (语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
int sum[100000];
int bk[100000];
char c[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  for(int i=0;i<3;i++)
  cin>>sum[i];
  for(int i=0;i<3;i++)
  cin>>c[i];
  sort(sum,sum+3);
  bk[‘A‘]=sum[0];
  bk[‘B‘]=sum[1];
  bk[‘C‘]=sum[2];
  for(int i=0;i<3;i++)
  cout<<bk[c[i]]<<" ";
}

J 弗洛格 (语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
int sum[100000];
int bk[100000];
char c[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  if(n<=26)
  cout<<27-n;
  else if(n>26)
  {
    n-=26;
    cout<<30-n+1;
  }
}

K 移动次数最少 (贪心)

洛谷试炼场的原题。。。原题好像是叫做移动纸牌。

解法

因为这里最左边的不能和最右边的联系。所以只有中间的那些能够左右的交换。

两个变量很麻烦,我们直接设置一个移动变量xi代表移动的卡牌数目

例如x1代表1给2的卡牌数

xi=ai-avg(ai代表当前手中的卡牌,avg代表平均最终的卡牌数)

线性扫描一下如果当前的牌经过之前的移动还不是avg的话那么答案加一次

最后输出即可

代码

#include <bits/stdc++.h>
using namespace std;
int num[1000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,re=0,sum=0;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>num[i],sum+=num[i];
  int avr=sum/n;
  for(int i=0;i<n-1;i++)
  {
    if(num[i]!=avr)
    {
        re++;
        num[i+1]+=num[i]-avr;   
    }
  }
  cout<<re;
}

L 小矮人 (语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
int sum[100000];
int bk[100000];
char c[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  for(int i=0;i<6;i++)
  {
    int t;
    cin>>t;
    bk[t]++;
  }
  for(int i=1;i<=7;i++)
  if(!bk[i])
  cout<<i;
}

M 小米 (语法基础)

代码

#include <bits/stdc++.h>
using namespace std;
int sum[100000];
int bk[100000];
char c[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int f,m,me;
  cin>>f>>m>>me;
  if(me==1)
  cout<<(f+m+13)/2;
  else if(me==0)
  cout<<(f+m-13)/2;
}

N 小球 (思维)

直接把所有的情况拿出来做个比较即可

解法

经过观察,我们发现如果要把一个红球放到蓝箱子里那么一定需要把一个蓝球放到红箱子里

那么这里肯定只有两种情况

①红球放到红箱子,蓝球放到蓝箱子

②红球或者蓝球数量少的全部放到另一个箱子,其他的还在原来的相同颜色的箱子内

为什么不可能有部分的情况?

因为移动或者不移动肯定会有一个价值的变化,而这个变化肯定也只有变大或者变小,不可能说你移动部分之后就会比移动全部的要变化的好

代码

#include <bits/stdc++.h>
using namespace std;
int num[1000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int a,b,c,d,e;
  cin>>a>>b>>c>>d>>e;
  int r1=a*c+b*d;
  int r2;
  if(a>b)
  r2=2*b*e+(a-b)*c;
  else if(a<b)
  r2=2*a*e+(b-a)*d;
  else
  r2=2*a*e;
  cout<<max(r1,r2);
}

O 找最长良序字符串 (字符串基础)

数据太小了,直接暴力就行了

代码

#include <bits/stdc++.h>
using namespace std;
int sum[100000];
int bk[100000];
char c[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  string a;
  cin>>a;
  int re=-1;
  for(int i=0;i<a.size();i++)
  {
    char t=a[i];
    int sum=1;
    for(int j=i+1;j<a.size();j++)
    {
      if(a[j]>t)
      sum++,t=a[j];
      else
      break;
    }
    re=max(re,sum);
  }
  cout<<re;
}

以上是关于2018-2019赛季多校联合新生训练赛第三场(2018/12/8)补题题解的主要内容,如果未能解决你的问题,请参考以下文章

2018-2019赛季多校联合新生训练赛第八场(2018/12/22)补题题解

2018-2019赛季多校联合新生训练赛第六场(2018/12/15)补题题解

Contest1592 - 2018-2019赛季多校联合新生训练赛第二场(部分题解)

多校联合训练第三场

2018年第四阶段组队训练赛第三场(BAPC2017 Preliminaries)

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)