2020团体程序设计天梯赛

L1-4 调和平均 (10分)

思路:把它们的倒数相加,然后再求它们的算术平均就好,一直wa了一个点不知道什么原因,然后只要把数组去了就对了。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    double a;
    double sum=0;
    for(int i=0;i<n;i++){
        cin>>a;//用数代替数组
        sum+=1.0/a;
    }
    sum=1.0*sum/n;
    sum=1.0/sum;
    printf("%.2lf\n",sum);
}

L1-6 吃火锅 (15分)

思路:比赛的时候用的是substr函数做模拟判断,然后wa了一个点,看了网上题解,其实还可以用find函数来做,比substr更方便。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    string p;
    string q="chi1 huo3 guo1";
    int ans=0,r=1,first=0;    
    while(1){
      getline(cin,p);
      if(p=="."){
          break;
      }
      if(p.find("chi1 huo3 guo1")!=-1) {
          if(first==0){
              first=r;    
          }ans++;
      }
      r++;
    }
    cout<<r-1<<endl;
    if(ans==0){
        cout<<"-_-#"<<endl;
        return 0;
    }
    cout<<first<<" "<<ans<<endl;
}

L2-4 网红点打卡攻略 (25分)

思路:我用的是map的嵌套,然后一个一个进行判断找出满足条件的攻略的条数,再把它们的花费和第几条攻略存到结构体数组进行枚举这个数组找出花费最少的即可,然后是22分找不到错在哪,

看了别人的思路,用数据结构新学的图论做,建一个邻接矩阵,然后枚举判断即可。

#include <iostream>
#include <vector>
#include <set>
#include <cstring>
using namespace std;
int main()
{
    int N, M;
    cin >> N >> M;
    int x, y, d;
    int v[250][250] = {0};
    memset(v, -1, sizeof(v));
    while (M--)
    {
        cin >> x >> y >> d;
        v[x][y] = d;
        v[y][x] = d;
    }
    int K;
    cin >> K;
    int cnt_ans = 0;
    int min_ans = 1e5;
    int sum_ans = 1e9 + 10;
    for (int j = 1; j <= K; j++)
    {
        cin >> M;
        vector<int> rode;
        rode.push_back(0);
        int T[252] = {0};
        while (M--)
        {
            cin >> x;
            rode.push_back(x);
            T[x]++;
        }
        int f = 0;
        for (int i = 1; i <= N; i++)
        {
            if (T[i] != 1)
            {
                f = 1;
                break;
            }
        }
        rode.push_back(0);
        if (f)
        {
            continue;
        }
        int sum = 0;
        for (int i = 1; i < rode.size(); i++)
        {
            if (v[rode[i - 1]][rode[i]] == -1)
            {
                f = 1;
                break;
            }
            else
            {
                sum += v[rode[i - 1]][rode[i]];
            }
        }
        if (f)
            continue;
        cnt_ans++;
        if (sum < sum_ans)
        {
            sum_ans = sum;
            min_ans = j;
        }
    }
    cout << cnt_ans << endl;
    cout << min_ans << " " << sum_ans;
    return 0;
}

L2-3 完全二叉树的层序遍历 (25分)

思路:因为给定的是后序遍历是左孩子->右孩子->父节点.而层序只要在建树的时候把他们反过来就好父节点->左孩子->右孩子。再用一个vis数组判断有无访问过就好。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=999;
int n,x;
int a[maxn];
int vis[maxn];
int tree[maxn];
void build(int i){
    if(vis[i]!=1){
        tree[i]=a[x--];//
        vis[i]=1;
    }
    if(vis[2*i+1]!=1){//
        build(i*2+1);
    }
    if(vis[2*i]!=1){//
        build(i*2);
    }
}
int main(){
    cin>>n;
    x=n;
    for(int i=1;i<=maxn;i++){
        vis[i]=1;
    }
    for(int i=1;i<=n;i++){
        cin>>a[i];
        vis[i]=0;
    }
    build(1);
    for(int i=1;i<=n;i++){
        if(i==1){
            cout<<tree[i];
        }
        else{
            cout<<" "<<tree[i];
        }
    }
    cout<<endl;
}

L2-2 口罩发放 (25分)

 思路:就是对着它的要求进行输入,不过比赛的时候太乱了。。看了半天没看懂拿不到分。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+10;
int n,m; // n天 至少间隔m天
struct node
{
    string name;
    string id; // 检验其合法性
    int tag; // 0 or 1
    int time; // 12:00 -> 12*60+0
    int order; // 当天申请的顺序
}p[N];
struct node1
{
    string name,id;
};
vector<node>g;
map<string,int>vis; // id上次拿到口罩的day
map<string,bool>f;
bool check(string s) // 检验id是否合法
{
    int len=s.length();
    if(len!=18)return 0;
    for(int i=0;i<len;i++)
    {
        if(s[i]<'0'||s[i]>'9')return 0;
    }
    return 1;
}
bool cmp(node s1,node s2)
{
    if(s1.time!=s2.time)return s1.time<s2.time;
    return s1.order<s2.order;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    vis.clear();
    g.clear();
    f.clear();
    for(int day=1;day<=n;day++)
    {
        int p1,p2;
        cin>>p1>>p2; // p1条记录,p2个人能拿到口罩
        int h,fen;
        char c;
        string name,id;
        int tag;
        int cnt=0;
        for(int i=1;i<=p1;i++)
        {
            cin>>name>>id>>tag>>h>>c>>fen;
            if(!check(id))continue; // 去除非法记录
            int time=h*60+fen;
            p[++cnt].name=name;
            p[cnt].id=id;
            p[cnt].tag=tag;
            p[cnt].time=time;
            p[cnt].order=cnt;
            if(tag==1)
            {
                if(!f[id])
                {
                    g.push_back({name,id});
                    f[id]=1;
                }
            }
        }
        sort(p+1,p+cnt+1,cmp);
        int tot=0;
        for(int i=1;i<=cnt;i++)
        {
            id=p[i].id;
            name=p[i].name;
            if(!vis[id]) // 这个人还没申请过
            {
                printf("%s %s\n",p[i].name.c_str(),p[i].id.c_str());
                vis[id]=day;
                tot++;
            }
            else
            {
                int last=vis[id];
                if(day-last<=m)continue; // m天之内申请过
                printf("%s %s\n",p[i].name.c_str(),p[i].id.c_str());
                vis[id]=day;
                tot++;
            }
            if(tot==p2)break;
        }
    }
    int sz=g.size();
    for(int i=0;i<sz;i++)
        printf("%s %s\n",g[i].name.c_str(),g[i].id.c_str());
    return 0;
}

 

posted @ 2020-12-06 17:51  liyongqishiwo  阅读(680)  评论(0编辑  收藏  举报