1. 程式人生 > >2018-2019賽季多校聯合新生訓練賽第六場(2018/12/15)補題題解

2018-2019賽季多校聯合新生訓練賽第六場(2018/12/15)補題題解

A 價錢統計(基礎程式設計能力)

這個考點還是比較個性的,怎麼四捨五入

解法

常規的講如果四捨五入整數位的話,那麼只需要在後面加個0.5然後強制轉換一下就可以了

這個卻要我們保留一位小數的四捨五入,那該怎麼做呢

實際上我們只需要把這個數乘以10然後加0.5,強制轉換後再除以10就可以了

程式碼

#include <bits/stdc++.h>
using namespace std;
double trans(double a)
{
  a*=10;
  a+=0.5;
  a=int(a);
  a/=10;
  return a;
}
int main()
{
  /*ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);*/
  double a,b,c,d;
  cin>>a>>b>>c>>d;
  double r1,r2,r3,r4,sum=0;
  r1=1.2*a;
  sum+=r1;
  r1=trans(r1);
  r2=3.5*b;
  sum+=r2;
  r2=trans(r2);
  r3=4.5*c;
  sum+=r3;
  r3=trans(r3);
  r4=5*d;
  sum+=r4;
  r4=trans(r4);
  sum=trans(sum);
  printf("%.1f\n%.1f\n%.1f\n%.1f\n%.1f",r1,r2,r3,r4,sum);
}

B 列印圖形 (語法基礎)

觀察得到規律比如A

就是A

B

ABA

A

是不是發現有規律?這一行就是從A到這個數然後再逆向輸出n-1項,如果是AB那麼n=2逆向輸出n=1的A加起來就是ABA

別忘記還有空格要列印

程式碼

#include <bits/stdc++.h>
using namespace std;
string st[1000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  char c;
  cin>>c;
  int id=c-'A'+1;
  for(int i=1;i<=id;i++)
  {
    string t="",tt="",ttt="";
    for(int j=0;j<i;j++)
    t+='A'+j;
    for(int j=0;j<t.size()-1;j++)
    tt+=t[j];
    reverse(t.begin(),t.end());
    for(int j=0;j<id-i;j++)
    ttt+=' ';
    st[i]=ttt+t+tt;
  }
  for(int i=id;i>=0;i--)
  {
    cout<<st[i];
    if(i!=0)
    cout<<"\n";
  }
}

C 數列計算I(語法基礎)

這裡還要保留小數,我不知道需不需要真的保留,不過我是保留了。並且最後輸出分式的時候要輸出.%0f我兩次wa就是因為最後double他科學計數了

程式碼

#include <bits/stdc++.h>
using namespace std;
int main()
{
  /*ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);*/
  int n;
  cin>>n;
  double t1=4;
  double t2=7,sum=0;
  for(int i=0;i<n;i++)
  {
    sum+=t1/t2;
    double t3=t1;
    t1=t2;
    t2+=t3;
  }
  printf("%.0f/%.0f\n",t2-t1,t1);
  sum*=100;
  sum+=0.5;
  sum=int(sum);
  sum/=100;
  printf("%.2f",sum);
}

D 單詞排序 (簡單排序)

程式碼

#include <bits/stdc++.h>
using namespace std;
struct node
{
  string nm;
  int a,b,c,d;
}num[1000000];
bool cmp(node a,node b)
{
  return a.a+a.b+a.c+a.d>b.a+b.b+b.c+b.d;
}
string st[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>st[i];
  sort(st,st+n);
  for(int i=0;i<n;i++)
  cout<<st[i]<<" ";
}

E 評獎(結構體排序)

程式碼

#include <bits/stdc++.h>
using namespace std;
struct node
{
  string nm;
  int a,b,c,d;
}num[1000000];
bool cmp(node a,node b)
{
  return a.a+a.b+a.c+a.d>b.a+b.b+b.c+b.d;
}
string st[10000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>st[i];
  sort(st,st+n);
  for(int i=0;i<n;i++)
  cout<<st[i]<<" ";
}

F 計算比分(簡單模擬)

首先分兩種情況

①不是第五局

②是第五局

然後這兩種情況的唯一區別是判斷勝利的條件不同。不是第五局那麼需要比分相差2且有一方已經大於等於25,是第五局那麼只需要大於等於15

之後到達條件記錄一下比分即可

程式碼

#include <bits/stdc++.h>
using namespace std;
struct node
{
  int a,b;
}jl[233];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  string a;
  cin>>a;
  int sa=0,sb=0,jx=0,ya=0,yb=0,p=0;
  for(int i=0;i<a.size();i++)
  {
    if(a[i]=='A')
    sa++;
    else if(a[i]=='B')
    sb++;
    if(jx<4)
    {
    if(sa>=sb+2&&sa>=25)
    {
      jl[p].a=sa;
      jl[p++].b=sb;
      sa=0;
      sb=0;
      ya++;
      jx++;
    }
    else if(sb>=sa+2&&sb>=25)
    {
      jl[p].a=sa;
      jl[p++].b=sb;
      sa=0;
      sb=0;
      yb++;
      jx++;
    }
  }
  else
  {
    if(sa>=sb+2&&sa>=15)
    {
      jl[p].a=sa;
      jl[p++].b=sb;
      sa=0;
      sb=0;
      ya++;
      jx++;
    }
    else if(sb>=sa+2&&sb>=15)
    {
      jl[p].a=sa;
      jl[p++].b=sb;
      sa=0;
      sb=0;
      yb++;
      jx++;
    }
  }
    if(ya==3||yb==3)
    break;
  }
  ya>yb?cout<<"A\n":cout<<"B\n";
  for(int i=0;i<p;i++)
  cout<<jl[i].a<<":"<<jl[i].b<<"\n";
}

G 手機號加密(字串模擬)

這個題細節還是比較多的

注意以下細節

①轉換到二進位制的時候高位補0

②轉換回來的時候低位補0外加擷取8位

其他的就是一個進位制轉換的問題,比較老生常談了

程式碼

#include <bits/stdc++.h>
using namespace std;
int qp(int a,int b)
{
  int re=1;
  for(int i=0;i<b;i++)
  re*=a;
  return re;
}
stack<char> st;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int a,sum=0,id;
  cin>>a;
  while(a)
  {
    st.push(a%2);
    a/=2;
  }
  string t="",tt="";
  while(st.size())
  {
    t+=char(st.top()+'0');
    st.pop();
  }
  for(int i=t.size();i<27;i++)
  t='0'+t;
  reverse(t.begin(),t.end());
  //cout<<t<<"\n";
  for(int i=0;i<t.size();i++)
  if(t[i]!='0')
  {
    id=i;
    break;
  }
  for(int i=id;i<t.size();i++)
  tt+=t[i];
  reverse(tt.begin(),tt.end());
  for(int i=0;i<tt.size();i++)
  sum+=(tt[i]-'0')*qp(2,i);
  stringstream sss;
  sss<<sum;
  string ss;
  sss>>ss;
  for(int i=ss.size();i<8;i++)
  ss='0'+ss;
  int st=ss.size()%8;
  for(int i=st;i<ss.size();i++)
  cout<<ss[i];
}

H 學生代表(數學)

就是找中位數,既然都是奇數了,那麼中位數可以排個序然後取num[n/2]即可,我不知道為啥我這個還re兩次。。。。

程式碼

#include <bits/stdc++.h>
using namespace std;
int t[555555],ans[555555],num[555][555];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  for(int i=0;i<n;i++)
  for(int j=0;j<n;j++)
  cin>>num[i][j];
  for(int i=0;i<n;i++)
  {
    for(int j=0;j<n;j++)
    t[j]=num[i][j];
    sort(t,t+n);
    ans[i]=t[n/2];
  }
  sort(ans,ans+n);
  cout<<ans[n/2];
}

I 拯救花園(貪心)

比較水的貪心題

貪心策略為:

破壞力/時間,小的放在前面

答案的演算法

①我們如果一個一個去拿去模擬也是可以,不過我覺得那樣比較麻煩,我們不如遞推一個時間陣列

②這個陣列是幹什麼用的呢?

(1)首先我們發現貪心越靠前的,算的時間越多。而且他們每次的破壞力又一樣,實際上可以只掃描一遍把破壞力乘以這個兔子總共破壞的時間即可

(2)這個時間陣列就是他們時間的字首和,然後兔子破壞力的總時間就是用最後最長的時間減去當前兔子所具有的字首時間

之後把答案輸出一下就可以了

程式碼

#include <bits/stdc++.h>
using namespace std;
struct node
{
  double l,r;
}num[1100];
bool cmp(node a,node b)
{
  return a.r/a.l<b.r/b.l;
}
int tim[1000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,sum=0;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>num[i].l>>num[i].r;
  sort(num,num+n,cmp);
  for(int i=0;i<n;i++)
  {
    if(i==0)
    tim[i]=num[i].l*2;
    else
    tim[i]=num[i].l*2+tim[i-1];
  }
  for(int i=0;i<n-1;i++)
  {
    sum+=num[i].r*(tim[n-1]-tim[i]);
  }
  cout<<sum;
}

J 摘李子(語法基礎)

程式碼

#include <bits/stdc++.h>
using namespace std;
int num[2000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,sum=0,ans=0;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>num[i],sum+=num[i];
  int r1=sum/n;
  ans+=sum%n;
  if(sum%n<r1)
  {
    ans+=n;
    r1--;
  }
  cout<<r1<<"\n"<<ans;
}

K 閱讀訓練(字首和)

把他們的字首和算出來去跟詢問的數比較即可。注意第一個數要-1

程式碼

#include <bits/stdc++.h>
using namespace std;
int sum[10000],cs[10000],ys[10000];
stack<char> st;
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,q;
  cin>>n>>q;
  for(int i=1;i<=n;i++)
  cin>>ys[i];
  for(int i=1;i<=q;i++)
  cin>>cs[i];
  for(int i=1;i<=n;i++)
  {
    if(i==1)
    sum[i]=ys[i]-1+sum[i-1];
    else
    sum[i]=ys[i]+sum[i-1];
  }
  for(int i=1;i<=q;i++)
  {
    for(int j=1;;j++)
    {
      if(sum[j]>cs[i])
      {
        cout<<j<<"\n";
        break;
      }
      else if(sum[j]==cs[i])
      {
        cout<<j<<"\n";
        break;
      }
    }
  }
}

L 填字遊戲(字串模擬)

我也不知道為啥好多人做不出來,這個題我可能運氣好昏迷一次就過了

說一下我的思路

①輸入地圖

②掃描一遍把數放進去

(1)這裡可以把遇到#就存之前的數,然後內部迴圈結束後也存一下數,這些數都是用字串存的,因為他們比較大可能有最多25位

③排序,定義規則先排字串的長度,長度小優先,長度一樣排字典序

④輸出,輸出的時候我還有空格,所以我又加了一些特判條件,最後輸出就過了

程式碼

#include <bits/stdc++.h>
using namespace std;
bool cmp(string a,string b)
{
  return a.size()==b.size()?a<b:a.size()<b.size();
}
char mp[100][100];
string st[1000000];
int main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,m,p=0;
  cin>>n>>m;
  for(int i=0;i<n;i++)
  for(int j=0;j<m;j++)
  cin>>mp[i][j];
  for(int i=0;i<n;i++)
  {
    string t="";
    for(int j=0;j<m;j++)
    {
      if(mp[i][j]!='#')
      t+=mp[i][j];
      else if(mp[i][j]=='#'&&t!="")
      {
        st[p++]=t;
        t="";
      }
    }
    st[p++]=t;
  }
  for(int i=0;i<p;i++)
  {
    string jk="";
    for(int j=0;j<st[i].size();j++)
    if(isdigit(st[i][j]))
    jk+=st[i][j];
    st[i]=jk;
  }
  sort(st,st+p,cmp);
  for(int i=0;i<p;i++)
  if(st[i]!="")
  {
    cout<<st[i];
    break;
  }
}

M 鋪地磚(遞推)

待填坑

高精度

公式好像是

f[i]=f[i-1]+2*f[i-2]