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市,
餐厅i在Si市,
你对每一家餐厅都有一个得分
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,
开关编号为1到n,
灯泡编号为
1
到
m
。
灯泡编号为1到m。
灯泡编号为1到m。
灯泡
i
连接了
k
i
个开关
:
开关
s
i
1
,
s
i
2
,
.
.
.
,和
s
i
k
i
。
灯泡i连接了ki个开关:开关si1,si2,...,和siki。
灯泡i连接了ki个开关:开关si1,si2,...,和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)包含了所有的可能性
从0到2n−1(n个1)包含了所有的可能性
时间复杂度:
O
10
∗
10
∗
2
10
O10*10*2^10
O10∗10∗210
#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 - 珠宝
题意: 以上是关于2021-2022-1 ACM集训队每周程序设计竞赛题解的主要内容,如果未能解决你的问题,请参考以下文章 BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛(10)题解 BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解 BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解
你的朋友送了你一个序列
D
你的朋友送了你一个序列D
你的朋友送了你一个序列D
这个序列
D
上一共有
n
个珠宝
这个序列D上一共有n个珠宝
这个序列D上一共有n个珠宝
按照从左到右的顺序
按照从左到右的顺序
按照从左到右的顺序
每个珠宝都有它的价值