2020年天梯赛补题报告

L1-3调和平均 (10分)

这题用数组会被扣一分,不用数组就能做对,不知道为啥...

#include <bits/stdc++.h>

using namespace std;

int n;
double res = 0;
int main()
{
    cin >> n;
    for(int i = 1;i <= n; ++ i){
        double x;
        cin >> x;
        res += 1.0/x;
    }
    res /= (1.0 * n);
    res = 1.0 / res;
    printf("%.2lf", res);
}

L1-6 吃火锅 (15分)

string里有一个 find() 函数挺好用的

#include <bits/stdc++.h>

using namespace std;

string str;
int cnt = 0, flag = 0, s;
int main()
{
    while(getline(cin, str), str != ".")
    {
        cnt ++;
        int f = 0, vis = 0;
        while(f != -1)
        {
            f = str.find("chi1 huo3 guo1", f);
            if(f == -1) break;
            if(flag == 0) flag = cnt;
            if(vis == 0) vis = 1, s ++;
            f ++;
        } 
    }
    if(flag == 0){
        cout << cnt << endl;
        puts("-_-#");
        return 0;
    }
    cout << cnt << endl;
    cout << flag << " " << s << endl;
}

L1-8 刮刮彩票 (20分)

他没刮开的地方也要算进sum里。。。

#include <bits/stdc++.h>

using namespace std;

int s, a[10][10], sum[110] = {0, 0, 0, 0, 0, 0
, 10000, 36, 720, 360, 80, 252, 108, 72, 54, 180, 72, 180,
119, 36, 306, 1080, 144, 1800, 3600};
bool flag[10][10], vis[110];
int main()
{
    for(int i = 1;i <= 3; ++ i){
        for(int j = 1;j <= 3; ++ j){
            cin >> a[i][j];
            if(a[i][j] != 0){
                vis[a[i][j]] = true;
            }
            else
            flag[i][j] = true;
        }
    }
    for(int i = 1;i <= 9; ++ i)
    if(!vis[i]) s = i;
    for(int i = 1;i <= 3; ++ i){
        for(int j = 1;j <= 3; ++ j){
            if(flag[i][j])
            a[i][j] = s;
        }
    }
    for(int i = 0;i < 3; ++ i){
        int x, y;
        cin >> x >> y;
        cout << a[x][y] << endl;
        flag[x][y] = true;
    }
    int k;
    cin >> k;
    s = 0;
    if(k >= 1 && k <= 3){
        for(int i = 1;i <= 3; ++ i){
//            if(flag[k][i])
            s += a[k][i];
        }
    }
    else if(k >= 4 && k <= 6){
        for(int i = 1;i <= 3; ++ i){
//            if(flag[i][k])
            s += a[i][k - 3]; // 出大问题.... 
        }
    }
    else if(k == 7){
        for(int i = 1;i <= 3; ++ i){
//            if(flag[i][i])
            s += a[i][i];
//            printf("a[%d][%d] = %d\n", i, i, a[i][i]);
        }
    }
    else{
        for(int i = 1, j = 3;i <= 3; ++ i, -- j){
            s += a[i][j];
        }
    }
//    cout << s << endl;
    cout << sum[s] << endl;
}

 L2-2 口罩发放 (25分)

这题要注意一些细节,比如身份证号必须由18位的数字构成,有可能会有重名的,排序时不能打乱原来有序时的顺序(即相等的元素不能交换位置)

#include <bits/stdc++.h>

using namespace std;
const int N = 1010;

struct node{
    string name;
    string id;
    bool sick;
    int th, tm;
    int s;
}a[N];

bool cmp(node a, node b)
{
    int t1 = a.th * 60 + a.tm, t2 = b.th * 60 + b.tm;
    if(t1 == t2){
        return a.s < b.s;
    }
    return a.th * 60 + a.tm < b.th * 60 + b.tm;
}
bool check(string str)
{
    if(str.size() != 18) return false;
    for(int i = 0;i < str.size(); ++ i){
        if(!isdigit(str[i])) return false;
    }
    return true;
}
int d, p, n, m, date, s;
map<string, int> mp;
vector<node> sick;
int main()
{
    cin >> d >> p;
    while(d --)
    {
        date ++;
        cin >> n >> m;
        for(int i = 1;i <= n; ++ i){
            cin >> a[i].name >> a[i].id
                >> a[i].sick;
            s ++;
            a[i].s = s;
            scanf("%d:%d", &a[i].th, &a[i].tm);     
    
            string id = a[i].id;
            if(a[i].sick && check(id)){
                int f = 1;
                for(int j = 0;j < sick.size(); ++ j){
                    if(id == sick[j].id){
                        
                        f = 0;
                        break;
                    }
                }
                if(f) sick.push_back(a[i]);
            }                    
        }
        
        sort(a + 1, a + 1 + n, cmp);
        
        int cnt = 0;
        
        for(int i = 1;i <= n; ++ i){
            string id = a[i].id;

            if(check(id) && cnt < m && (mp[id] == 0 || (date - mp[id] >= p + 1))){
                mp[id] = date;
                cout << a[i].name << " " << a[i].id << endl;
                cnt ++;
            }
            
        }
        
    }
    
    for(int i = 0;i < sick.size(); ++ i){
        cout << sick[i].name << " " << sick[i].id << endl;
    }
    
}

网红点打卡攻略 (25分)

需要注意的就是他说的 “在每个网红点打卡仅一次”, 所以如果两个网红点没有路时不能通过其它的网红点到达(好像可以通过家再到达另一个网红点,但测试样例中好像没有这种情况),剩下的就是按着他的方案来就行了。

#include <bits/stdc++.h>
 
using namespace std;

int n, m, k, sum, cnt, a[220][220];
bool vis[220];
pair<int, int> ans;
int main()
{
    ans.second = 0x3f3f3f3f;
    cin >> n >> m;
    while(m --)
    {
        int x, y, z;
        cin >> x >> y >> z;
        a[x][y] = z;
        a[y][x] = z;
    }
    cin >> k;
    while(k --)
    {
        memset(vis, 0, sizeof(vis));
        cnt ++;
        int w;
        cin >> w;
        int tmp;
        cin >> tmp;
        vis[tmp] = true;
        int cost = 0, f = 1;
        
        if(a[0][tmp] == 0){
            f = 0;
        }
        cost += a[0][tmp];
        if(w != n) f = 0;
        for(int i = 2;i <= w; ++ i){
            int x;
            cin >> x;
            if(vis[x]) f = 0;
            vis[x] = true;
            if(a[tmp][x] == 0) f = 0;
            else cost += a[tmp][x];
            tmp = x;
        }
        if(a[tmp][0] == 0) f = 0;
        else cost += a[tmp][0];
         
        if(f) sum ++;
        if(f && cost < ans.second){
            ans.second = cost;
            ans.first = cnt;
        }
    }
    cout << sum << endl;
    cout << ans.first << " " << ans.second << endl;
}

 

posted @ 2020-12-01 18:25  IIlIlIlI  阅读(114)  评论(0编辑  收藏  举报