2021-2022-1 ACM集训队每周程序设计竞赛题解

Posted ZZXzzx0_0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-2022-1 ACM集训队每周程序设计竞赛题解相关的知识,希望对你有一定的参考价值。

A - 苹果派

题意
你有 a 个苹果和 p 个苹果片 你有a个苹果和p个苹果片 你有a个苹果和p个苹果片
1 个苹果可以制作 3 个苹果片 1个苹果可以制作3个苹果片 1个苹果可以制作3个苹果片
2 个苹果片可以制作 1 个苹果派 2个苹果片可以制作1个苹果派 2个苹果片可以制作1个苹果派
问一共可以制作多少个苹果派 问一共可以制作多少个苹果派 问一共可以制作多少个苹果派
0 < = a , p < = 100 0 <= a , p <= 100 0<=a,p<=100
思路
模拟 模拟 模拟
时间复杂度 O 1 O1 O1

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\\n" 
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define pb push_back
#define y second 
#define x first 
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f ;
const int N = 1e6 + 10 , M = 2010 , mod = 1e9 + 7 ;
 
signed main()

    int n , p ;
    cin >> n >> p ;
    
    p += 3 * n ;
    
    de(p/2) ;
    
    return 0;

 

B - 餐馆指南

题意
你决定写一本介绍好餐馆的书。 你决定写一本介绍好餐馆的书。 你决定写一本介绍好餐馆的书。
你想介绍的餐厅有 N 家 : 餐厅 1 ,餐厅 2 , . . . 餐厅 n 你想介绍的餐厅有N家 : 餐厅1,餐厅2,...餐厅n 你想介绍的餐厅有N:餐厅1,餐厅2...餐厅n
1 < = n < = 100. 1 <= n <= 100. 1<=n<=100.

餐厅 i 在 S i 市, 餐厅i在Si市, 餐厅iSi市,
你对每一家餐厅都有一个得分 p 你对每一家餐厅都有一个得分p 你对每一家餐厅都有一个得分p
1 < = p < = 100 1 <= p <= 100 1<=p<=100
没有两家餐馆得分相同。 没有两家餐馆得分相同。 没有两家餐馆得分相同。

您要按以下顺序介绍餐厅 : 您要按以下顺序介绍餐厅: 您要按以下顺序介绍餐厅:
餐厅按其城市名称的字典顺序排列。 餐厅按其城市名称的字典顺序排列。 餐厅按其城市名称的字典顺序排列。
如果同一个城市有多家餐厅, 如果同一个城市有多家餐厅, 如果同一个城市有多家餐厅,
则按得分降序排列。 则按得分降序排列。 则按得分降序排列。

按照书中介绍的顺序打印餐厅的编号。 按照书中介绍的顺序打印餐厅的编号。 按照书中介绍的顺序打印餐厅的编号。
思路
结构体自定义排序 结构体自定义排序 结构体自定义排序
时间复杂度 O n l o g n Onlogn Onlogn

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\\n" 
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define pb push_back
#define y second 
#define x first 
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f ;
const int N = 1e6 + 10 , M = 2010 , mod = 1e9 + 7 ;

struct ai
    int id , score ; // 编号 , 得分
    string city ; // 城市名称
q[M] ;

bool cmp(ai a , ai b)

    if(a.city == b.city) return a.score > b.score ;  // 城市字典序相等的时候按照得分大于(逆序)排序
    else return a.city < b.city ;    //  否则按照字典序小于(顺序)排序


signed main()

    int n ;
    cin >> n ;
    
    fer(i,1,n)
    
        cin >> q[i].city >> q[i].score ;
        q[i].id = i ;
    
    
    sort(q + 1 , q + 1 + n , cmp) ;
    
    fer(i,1,n) 
    
        cout << q[i].id << "\\n" ;
    
    
    return 0;

C - 开关

题意
我们有“开”和“关”状态的 n 个开关和 m 个灯泡。 我们有“开”和“关”状态的n个开关和m个灯泡。 我们有状态的n个开关和m个灯泡。
开关编号为 1 到 n , 开关编号为1到n, 开关编号为1n
灯泡编号为 1 到 m 。 灯泡编号为1到m。 灯泡编号为1m

灯泡 i 连接了 k i 个开关 : 开关 s i 1 , s i 2 , . . . ,和 s i k i 。 灯泡i连接了ki个开关:开关si1,si2,...,和siki。 灯泡i连接了ki个开关:开关si1si2...,和siki
对于灯泡 i 连接的这些开关中如果打开的开关数量 m o d 2 等于 p [ i ] ,灯泡 i 会被点亮。 对于灯泡i连接的这些开关中如果打开的开关数量mod2等于p[i],灯泡i会被点亮。 对于灯泡i连接的这些开关中如果打开的开关数量mod2等于p[i],灯泡i会被点亮。

开关的“开”和“关”状态有多少种组合可以点亮所有灯泡? 开关的“开”和“关”状态有多少种组合可以点亮所有灯泡? 开关的状态有多少种组合可以点亮所有灯泡?
1 < = n , m < = 10 1 <= n , m <= 10 1<=n,m<=10
1 < = k i < = n 1 <= ki <= n 1<=ki<=n
p [ i ] = 0 / 1 p[i] = 0 / 1 p[i]=0/1
思路
考虑 n 的范围最大只有 10 考虑n的范围最大只有10 考虑n的范围最大只有10
我们可以暴力枚举所有开关打开或者关闭的状态 我们可以暴力枚举所有开关打开或者关闭的状态 我们可以暴力枚举所有开关打开或者关闭的状态

考虑使用状态压缩来做 考虑使用状态压缩来做 考虑使用状态压缩来做
用一个二进制数来表示当前 n 个开关的打开状态 用一个二进制数来表示当前n个开关的打开状态 用一个二进制数来表示当前n个开关的打开状态

假设现在的二进制数是 010101 假设现在的二进制数是010101 假设现在的二进制数是010101
0 表示没选这个开关, 1 表示选了这个开关 0表示没选这个开关,1表示选了这个开关 0表示没选这个开关,1表示选了这个开关
选了 1 的开关即为第 1 个第 3 个第 5 个 选了1的开关即为第1个第3个第5个 选了1的开关即为第1个第3个第5

从 0 到 2 n − 1 ( n 个 1 ) 包含了所有的可能性 从0到2^n-1(n个1)包含了所有的可能性 02n1(n1)包含了所有的可能性
时间复杂度 O 10 ∗ 10 ∗ 2 10 O10*10*2^10 O1010210

#include <bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define der(i,a,b) for(re i = a ; i >= b ; -- i)
#define de(x) cout << x << "\\n" 
#define sf(x) scanf("%lld",&x)
#define pll pair<int,int> 
#define re register int
#define int long long 
#define pb push_back
#define y second 
#define x first 
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f ;
const int N = 1e6 + 10 , M = 2010 , mod = 1e9 + 7 ;

int n , m ; // n个开关 m个灯泡
vector<int> q[M] ;
int p[M] ;

signed main()

    cin >> n >> m ;
    
    fer(i,1,m)
    
        int k ;
        sf(k) ;
        
        fer(j,1,k)
        
            int x ;
            sf(x) ;
            q[i].pb(x) ;
        
    
    
    fer(i,1,m) sf(p[i]) ;
    
    int res = 0 ;  // res 表示最后的答案
    
    for(int i = 0 ; i < 1 << n ; i ++)  // 枚举所有可能的二进制状态
    
        bool st[11] = 0 ;             //  初始化所有开关都关闭
        for(int j = 0 ; j < n ; j ++)   //  判断哪些开关开了
        
        	// 如果i这个二进制数的第j位是1的话
            if(i >> j & 1) st[j+1] = 1 ;  // 开关编号从1开始  所以+1
        
        
        int cnt = 0 ;  // cnt表示当前打开的灯泡数量
        for(int j = 1 ; j <= m ; j ++)  //  枚举所有灯泡  判断当前这个灯泡是否打开
        
            int k = 0 ;         //  k表示当前这个灯泡有几个对应的开关打开
            for(int z = 0 ; z < q[j].size() ; z ++)  // 枚举这个灯泡的所有开关
            
                if(st[q[j][z]]) k ++ ;   //  如果这个开关打开了 k ++
            
            if(k % 2 == p[j]) cnt ++ ;  //   如果 k % 2 == p[j] 说明这个灯泡被打开了  cnt ++
        
        
        if(cnt == m) res ++ ;  // 如果所有灯泡都打开了  res ++
    
    
    cout << res << "\\n" ;
    
    return 0;

D - 珠宝

题意
你的朋友送了你一个序列 D 你的朋友送了你一个序列D 你的朋友送了你一个序列D
这个序列 D 上一共有 n 个珠宝 这个序列D上一共有n个珠宝 这个序列D上一共有n个珠宝
按照从左到右的顺序 按照从左到右的顺序 按照从左到右的顺序
每个珠宝都有它的价值

以上是关于2021-2022-1 ACM集训队每周程序设计竞赛题解的主要内容,如果未能解决你的问题,请参考以下文章

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛(10)题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解

2021-2022-1 ACM集训队每周程序设计竞赛题解

2021-2022-1 ACM集训队每周程序设计竞赛题解