2024天梯赛

L1-3帮助色盲

读题仔细点吧,背景还是可以看一下的

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f

void solve(){
	int a,b;
    cin >> a >> b;
    //第一行只输出提示(红灯输出"biii" 绿灯输出"dudu") or 不提示(-)
    if(b || a == 2){
        cout << "-";
    }else{
        if(a == 1) cout << "dudu";
        else cout << "biii";
    }
    cout << endl;
    //第二行只输出行不行动 绿灯行 红灯黄灯停
    if(a == 1) cout << "move";
    else cout << "stop";

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L1-4四项全能

题意:给定全班总人数为 \(n\),其中有 \(m\) 项技能,分别有 \(k1、k2、……、k_m\) 个人会,问至少有多少人$ m$ 项都会。

前面那题给晃了一下,这题脑子都不转了。

思路:假设技能点总数为\(sum\),假设每个人都会\(m-1\)项,则剩下\(sum-(m-1) \times n\)个技能点,一定是属于四项全能的人的。注意最小人数为\(0\)

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
int n, m;
int sum;
void solve(){
    cin >> n >> m;
    for(int i = 1; i <= m ; i ++){
        int x; cin >> x;
        sum += x;
    }
    cout << max((int)0,sum - n*(m-1));

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L1-5别再来这么多猫娘了!

题意:给\(n\)个违禁词和一个字符串,问字符串中的违禁词是否小于\(k\),如果是,则将违禁词替换成\(<censored>\)后输出,否则输出\(He \ Xie\ Ni \ Quan\ Jia!\)

注意:

1.getline读入字符串之前,如果前面有输入,一定要把'\n'给getchar()了(如果多行getline不用)

2.待检查字符串可能出现\(<censored>\),\(@\),\(!\)等等符号,所以要找一个在数据中待见字符串没有出现过的才能通过,所以只能一个个换着试,不得不说,题目和数据都真ex。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
int n, m;
string s[110];
string res;
int cnt;
void solve(){
    cin >> n;
    for(int i = 0 ; i < n ; i ++) cin >> s[i];
    cin >> m; getchar();
    getline(cin,res);
    //cout << res << endl;
    for(int i = 0 ; i < n ; i ++){
        int pos = res.find(s[i]);
        //cout << res << " " << s[i] << " " << pos << endl;
        while(pos != -1){
            cnt ++;
            res = res.substr(0,pos) + "@!@#!" + res.substr(pos+s[i].size());
            pos = res.find(s[i]);
        }
    }
    if(cnt >= m){
        cout << cnt << endl;
        cout << "He Xie Ni Quan Jia!";
    }else{
        int pos = res.find("@!@#!");
        while(pos != -1){
            res = res.substr(0,pos) + "<censored>" + res.substr(pos+5);
            pos = res.find("@!@#!");
        }
        cout << res;
    }
}
signed main(){
    //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L1-6兰州牛肉面

简单模拟

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
int n;
double p[110];
int cnt[110];
double sum;
void solve(){
    cin >> n;
    for(int i = 1 ; i <= n ; i ++) cin >> p[i];
    int x, y;
    cin >> x >> y;
    while(x != 0){
        sum += (double)y * p[x];
        cnt[x] += y;
        cin >> x >> y;
    }
    
    for(int i = 1; i <= n ; i ++){
        cout << cnt[i] << endl;
    }
    printf("%.2f\n",sum);
}
signed main(){
    //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L1-103 整数的持续性

看清楚题意,整数连续性是指多次操作后变成个位数,而不是回到自己的数字!!!因为是乘法,所以不需要几步,就能判断一个数的连续性。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
map<int,int> mp;
int mx;
int get(int x){
    if(x/10==0){
        mp[x] = 0;
        return 0;
    }
    int now = x,t,cnt = 0;
    while(now/10){
        t = now;
        int s = 1;
        while(t){
            s *= t % 10;
            t /= 10;
        }
        now = s;
        cnt++;
    }
    mp[x] = cnt;
    return cnt;
}
void solve(){
    int l ,r ;
    cin >> l >> r;
    for(int i = l ; i <= r ; i ++){
        mx = max(mx,get(i));
    }
    cout << mx << endl;
    int f = 1;
    for(auto [x,y] : mp){
        if(y == mx) 
        {
            if(f) f = 0;
            else cout << " ";
            cout << x;
        }
                
    }
}
signed main(){
    //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L1-8九宫格

看清楚题目要求!有两个

1.每个\(3 \times 3\)的小格子里\(1-9\)只能出现一次

2.整个\(9 \times 9\)的大的里,每行每列\(1-9\)也只能出现一次

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
int n;
int a[10][10];

void solve(){
    int f = 1;
    for(int i = 1 ; i <= 9 ; i ++)
        for(int j = 1 ; j <= 9 ; j ++)
            cin >> a[i][j];
    for(int i = 1 ; i <= 7 ; i += 3){
        for(int j = 1 ; j <= 7 ; j += 3){
            vector<bool> vis(10,false);
            for(int x = i ; x <= i + 2 ; x ++){
                for(int y = j ; y <= j + 2 ; y ++){
                    if(a[x][y] >= 1 && a[x][y] <= 9) vis[a[x][y]] = true;
                }
            }
            for(int o = 1; o <= 9 ; o ++) if(vis[o] == false) f = 0;
        }
    }
    for(int x = 1; x <= 9 ; x ++){
        vector<bool> vis(10,false);
        for(int y = 1; y <= 9 ; y ++){
            if(a[x][y] >= 1 && a[x][y] <= 9) vis[a[x][y]] = true;
        }
        for(int o = 1; o <= 9 ; o ++) if(vis[o] == false) f = 0;
    }
    for(int y = 1; y <= 9 ; y ++){
        vector<bool> vis(10,false);
        for(int x = 1; x <= 9 ; x ++){
            if(a[x][y] >= 1 && a[x][y] <= 9) vis[a[x][y]] = true;
        }
        for(int o = 1; o <= 9 ; o ++) if(vis[o] == false) f = 0;
    }
    cout << f << endl;
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    cin >> _;
    while(_--) solve();
    return 0;
}

L2-1 鱼与熊掌

赛时用\(set\)过了,但是数据水了,输入的时候就是\(O(nklogk)\),已经\(T\)

所以考虑使用\(vector\)然后排序(如果排序,和上面一样是\(O(nklogk)\)了,而观察输入,一定是顺序的,好巧!),二分查找,复杂度\(O(Qklog(k))\)

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
const int N = 1e5 + 10;
int n, m;
vector<int> v[N];
void solve(){
    cin >> n >> m;
    for(int i = 1 ; i <= n ; i ++){
        int k; cin >> k;
        for(int j = 1 ; j <= k ; j ++){
            int t; cin >> t;
            v[t].push_back(i);
        }
    }
    int t; cin >> t;
    while(t--){
        int x, y; cin >> x >> y;
        int cnt = 0;
        for(auto it : v[x]){
            int pos = lower_bound(v[y].begin(),v[y].end(),it) - v[y].begin();
            if(v[y][pos]==it) cnt ++; 
        }
        cout << cnt << endl;
    }
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L2-2懂蛇语

用缩写映射到每个缩写对应的话就可以

坑点:

1.取缩写的时候,第一个字符可能是空格,每个单词之间的空格可能不为1

2.翻译的话里面可能有重复的都要并列输出出来

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
const int N = 2e5 + 10;
int n; 
map<string,multiset<string>> mp;
string get(string s){
    int len = s.size();
    string res = "";
    for(int i = 0 ; i < len ; i ++){
        while(s[i] == ' ' && i < len) i++;
        res += s[i];
        while(s[i] != ' ' && i < len) i++;
    }
    return res;
}
void solve(){
    cin >> n; getchar();
    string s, t;
    for(int i = 1 ; i <= n ; i ++){
        getline(cin,s); t = get(s);
        mp[t].insert(s);
    }
    int q; cin >> q; getchar();
    for(int i = 1 ; i <= q; i ++){
        getline(cin,s); t = get(s);
        if(mp.count(t))
        {
            int first = 1;
            for(auto it : mp[t]){
                if(first) first = 0;
                else cout << "|";
                cout << it;
            }
        }else{
            cout << s;
        }
        cout << endl;
    }
}
signed main(){
    //ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L2-3满树的遍历

数据结构简单题

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
const int N = 1e5 + 10;
int n, root, k;
vector<int> e[N],ans;
int f = 1;
void dfs(int r){
    ans.push_back(r);
    if(e[r].size() == 0) return;
    if(f && (int)e[r].size() != k) f = 0;
    k = max((int)e[r].size(),k);
    for(auto v : e[r]){
        dfs(v);
    }
}
void solve(){
    cin >> n;
    int x;
    for(int i = 1 ; i <= n ; i ++){
        cin >> x;
        if(x == 0) root = i;
        else e[x].push_back(i);
    }
    k = e[root].size();
    dfs(root);
    cout << k << " " << (f?"yes":"no") << endl;
    int fir = 1;
    for(auto it : ans){
        if(fir) fir = 0;
        else cout << " ";
        cout << it ;
    }
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}

L2-4吉利矩阵

其实赛时思路一样,但是没想清楚怎么写,最后半个小时都没写对,这个时候就该果断放弃写L3-1的,唉,差一点点,还是太菜了

思路:爆搜,注意剪枝

1.一个\(n\times n\)大小的矩阵,只用枚举 \((n-1) \times (n-1)\) 大小的矩阵即可

2.枚举每一个数的时候,需要考虑前面的和,只需要枚举到\(k-sum\)

3.所以只需要记录当前每行,每一列的和即可,方便了2,最后也方便1的检查,即查看最右下角需要填的数是否在\(0-l\)之间

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
//#define int long long
int row[5],col[5];
int k, n;
int cnt;
void dfs(int x,int y){
	if(y == n){
		x ++; y = 1;
	}
	if(x == n){
		int sumr = 0 , sumc = 0;
		for(int i = 1 ; i <= n - 1 ; i ++) sumr += (k - row[i]);
		for(int i = 1 ; i <= n - 1 ; i ++) sumc += (k - col[i]);
		//实际上sumr和sumc相同,都是左上角(n-1)*(n-1)个数字之和
		//所以不用计算最右小角的数是否合法 右下角的数字一定是(k - sumr/sumc) >= 0 就ok
		if(sumr <= k && sumc <= k) cnt++;
		return ;	
	}
	for(int i = 0 ; i <= k - row[x] && i <= k - col[y] ; i ++){//剪枝
		row[x] += i, col[y] += i;
		dfs(x , y + 1);
		row[x] -= i, col[y] -= i;
	}
}
void solve()
{  
   	cin >> k >> n;
   	dfs(1, 1);
    cout << cnt;
}
signed main()
{
    //ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int _;
    //cin >> _;
    _ = 1;
    while(_--) solve();
    return 0;
}

L3-1夺宝大赛

从大本营出发,一遍BFS就可以算出每个点到大本营的最短路,然后判断就可以

有趣的是我把判断大本营那段代码写成了==0,居然过了两个样例还过了前三个测试点,简直了,还让我找了半天的错。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 0x3f3f3f3f
const int N = 1e5 + 10;
int n, m, x, y;
int g[110][110];
int dis[110][110];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
map<int,int> cnt,ans;
void bfs(int x,int y){
    queue<pair<int,int> > q;
    q.push({x,y});
    dis[y][x] = 1;
    while(q.size()){
        auto [x,y] = q.front() ; q.pop();
        for(int i = 0 ; i < 4 ; i ++){
            int nx = x + dx[i], ny = y + dy[i];
            if(nx > n || nx < 1 || ny > m || ny < 1) continue;
            if(g[nx][ny] == 0) continue;
            if(!dis[nx][ny]||dis[nx][ny] > dis[x][y] + 1){
                dis[nx][ny] = dis[x][y] + 1;
                q.push({nx,ny});
            }
        }
    }
}
void solve(){
    cin >> n >> m;
    for(int i = 1; i <= n ; i ++)
        for(int j = 1; j <= m ; j ++){
            cin >> g[i][j];
            if(g[i][j] == 2) x = i , y = j;
        }
    bfs(x,y);
    int q, o, p;
    cin >> q;
    for(int i = 1 ; i <= q ; i ++){
        cin >> o >> p;
        if(dis[p][o] == 0 || dis[p][o] == 1) continue;
        int path = dis[p][o];
        cnt[path] ++;
        //cout << i << " " << path << endl;
        ans[i] = path;
    }
    int mn = LONG_LONG_MAX,res;
    for(auto [x,y] : ans){
        if(cnt[y] == 1 && mn > y){
            res = x;
            mn = y;
        }
    }
    if(mn != LONG_LONG_MAX)cout << res << " " << mn;
    else cout << "No winner.";
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int _ = 1;
    //cin >> _;
    while(_--) solve();
    return 0;
}
posted @ 2024-04-25 11:11  xde_yt  阅读(50)  评论(0编辑  收藏  举报