当前位置:网站首页>2021-2022-2 ACM集训队每周程序设计竞赛(8)题解
2021-2022-2 ACM集训队每周程序设计竞赛(8)题解
2022-04-23 19:12:00 【ZZXzzx0_0】
A. 21点游戏
题意:
给你三个数A1 , A2 , A3 ,
如果A1 + A2 + A3 >= 22 , 输出 bust
否则输出 win
思路:
模拟
时间复杂度: O 1 O1 O1
#include<bits/stdc++.h>
using namespace std ;
const int N = 1e6 + 10 ;
int main()
{
int a , b , c ;
cin >> a >> b >> c;
int s = a + b + c ;
if(s >= 22) puts("bust") ;
else puts("win") ;
return 0 ;
}
B. 回文游戏
题意:
给你一个字符串S,
你可以修改S的任意一个字符,
问最少需要修改多少次,使得S变成一个回文串。
思路:
双指针
时间复杂度: O n On On
#include<bits/stdc++.h>
using namespace std ;
const int N = 1e6 + 10 ;
char s[N] ;
int main()
{
cin >> s + 1 ;
int n = strlen(s + 1) ;
int res = 0 ;
for(int i = 1 , j = n ; i < j ; i ++ , j --)
{
if(s[i] != s[j]) res ++ ;
}
cout << res ;
return 0 ;
}
C. 好人 or 坏人 ?
题意:
有n个人在玩一个游戏,
这个游戏是这样的,我们将n个人分为好人和坏人,也有可能n个人都是好人或者都是坏人
好人说的话一定是对的,坏人说的话有可能对,也有可能不对。
现在给你每个人对另外一些人的判断,
问好人最多有多少个
思路:
注意到n最多有15个人,每个人要么好人要么坏人,所以暴力枚举所有可能性,时间复杂度为 2 15 2^{15} 215,
这里可以用状态压缩来枚举,或者用dfs枚举。
对每一种情况来说,每个人是好人还是坏人都是已知的。
那么好人说的话一定是对的,如果出现了冲突,则说明这种情况不行。
可以的话,更新一下好人人数即可。
时间复杂度: O ( 2 15 ∗ n 2 ) O(2^{15}*n^{2}) O(215∗n2)
#include <bits/stdc++.h>
using namespace std;
int n,m,x,y,z;
vector<pair<int ,int> > a[20];
int main(){
cin>>n;
for (int i=0;i<n;i++){
cin>>m;
for (int j=0;j<m;j++){
cin>>x>>y;
a[i].push_back(make_pair(x-1,y));
}
}
for (int i=0;i<1<<n;i++){
int f=1;
for (int j=0;j<n;j++){
if (i>>j&1){
for (pair<int,int>k:a[j]){
if ((i>>k.first&1)!=k.second) f=0;
}
}
}
if (f) z=max(z,__builtin_popcount(i));
}
cout<<z<<endl;
return 0;
}
D. 异或和
题意:
给你n个数的数组
a 1 a_1 a1 a 2 a_2 a2 … a n a_n an
求( ∑ i = 1 n − 1 ∑ j = i + 1 n ( a [ i ] ⊕ a [ j ] ) \sum_{i=1}^{n - 1}{\sum_{j=i + 1}^{n}{(a[i] \oplus a[j])}} ∑i=1n−1∑j=i+1n(a[i]⊕a[j])) % ( 1 0 9 10^9 109 + 7)
A ⊕ B A\oplus B A⊕B 表示A异或B , 也表示为(a ^ b)
思路:
位运算需要拆解每一位来看,
我们假设 b [ k ] [ i ] b[k][i] b[k][i]数组表示 a i a_i ai的二进制表示下的第 k k k位是 1 1 1还是 0 0 0
所以我们只需要求出每一位上 ∑ i = 1 n − 1 ∑ j = i + 1 n ( b [ k ] [ i ] ⊕ b [ k ] [ j ] ) \sum_{i=1}^{n - 1}{\sum_{j=i + 1}^{n}{(b[k][i] \oplus b[k][j])}} ∑i=1n−1∑j=i+1n(b[k][i]⊕b[k][j])的值
答案累加上 2 k ∗ ∑ i = 1 n − 1 ∑ j = i + 1 n ( b [ k ] [ i ] ⊕ b [ k ] [ j ] ) 2^k * \sum_{i=1}^{n - 1}{\sum_{j=i + 1}^{n}{(b[k][i] \oplus b[k][j])}} 2k∗∑i=1n−1∑j=i+1n(b[k][i]⊕b[k][j])即可
现在考虑只有一个0/1的数组,如何求 ∑ i = 1 n − 1 ∑ j = i + 1 n ( b [ k ] [ i ] ⊕ b [ k ] [ j ] ) \sum_{i=1}^{n - 1}{\sum_{j=i + 1}^{n}{(b[k][i] \oplus b[k][j])}} ∑i=1n−1∑j=i+1n(b[k][i]⊕b[k][j])
因为只有 0 / 1 0/1 0/1两种情况
偶数个 1 1 1异或等于 0 0 0
奇数个 1 1 1异或等于 1 1 1
因此
∑ i = 1 n − 1 ∑ j = i + 1 n ( b [ k ] [ i ] ⊕ b [ k ] [ j ] ) = 1 的 个 数 ∗ 0 的 个 数 \sum_{i=1}^{n - 1}{\sum_{j=i + 1}^{n}{(b[k][i] \oplus b[k][j])}}=1的个数*0的个数 ∑i=1n−1∑j=i+1n(b[k][i]⊕b[k][j])=1的个数∗0的个数
时间复杂度: O n l o g n Onlogn Onlogn
#include<bits/stdc++.h>
using namespace std ;
#define int long long
const int N = 1e6 + 10 , mod = 1e9 + 7 ;
int res , n , a[N] ;
signed main()
{
cin >> n ;
for(int i = 1 ; i <= n ; i ++)
scanf("%lld" , &a[i]) ;
for(int j = 0 ; j < 60 ; j ++)
{
int cnt = 0 , s ;
for(int i = 1 ; i <= n ; i ++)
{
if(a[i] >> j & 1) cnt ++ ;
}
s = cnt * (n - cnt) % mod ;
for(int i = 0 ; i < j ; i ++) s = s * 2 % mod ;
res += s , res %= mod ;
}
cout << res ;
return 0 ;
}
E. 吃菜
题意:
有n盘菜,每盘菜需要 a i a_i ai的时间去吃,有 b i b_i bi的美味度。
现在有如下规则:
- 点了一盘菜之后,只能将其吃完后才能点下一盘菜。
- t 时刻过后就不能再点菜了,但是依旧可以吃菜。
- 每种菜只能点一次。
最后问最后能够得到的最大美味度是多少。
思路:
如果不考虑第二条规则,很明显是个01背包问题,
我们假设 f [ j ] f[j] f[j]表示时间为 j j j的情况下的最大美味度,
f [ j ] = f [ j − a [ i ] ] + b [ i ] f[j] = f[j - a[i]] + b[i] f[j]=f[j−a[i]]+b[i]
现在考虑加上第二条规则,
也就是说我们可以在 i < t i < t i<t的任意一个时刻美味度加上 b i b_i bi,
显然需要对 a i a_i ai从小到大排序,因为时间长的放在最后去吃的收益最大。
时间复杂度: O n 2 On^2 On2
#include<bits/stdc++.h>
using namespace std ;
#define pll pair<int,int>
#define y second
#define x first
const int N = 1e6 + 10 ;
int n , m ;
pll q[N] ;
int f[N] ;
int res ;
signed main()
{
cin >> n >> m ;
for(int i = 1 ; i <= n ; i ++)
cin >> q[i].x >> q[i].y ;
sort(q + 1 , q + 1 + n) ;
for(int i = 1 ; i <= n ; i ++)
{
for(int j = 0 ; j < m ; j ++)
{
res = max(res , f[j] + q[i].y) ;
}
for(int j = m ; j >= q[i].x ; j --)
{
f[j] = max(f[j] , f[j - q[i].x] + q[i].y) ;
}
}
cout << max(res , f[m]) ;
return 0;
}
F: 矩形
题意:
给定n个坐标系上的点( x i x_i xi, y i y_i yi)
若有如下图所示的三个点(黑点)就可以构造岀一个新的点(红点)。求可构造的点的最多的个数。

思路:
一个可以操作的地方只要是连通的区域,就可以把这块区域的点填满。

蓝色为已有的点,红色是后来加上的点,可以通过一点点加进来。
只要在这个区域内的,线上的点都可以被填上。
求出每个块内,所有点在的横线和竖线个数,相乘就是所有点。
怎么求有多少个区域呢?我们可以利用并查集,把每个点的横坐标和纵坐标绑在一个集合里,这样以后出现相同竖线的和相同横线的都会被绑进来,形成一个大集合,但是单独计算的时候,只把竖线和横线单独计算。
最后减去已有的点即可。
时间复杂度: O n On On
#include<bits/stdc++.h>
using namespace std ;
const int N = 1e6 + 10 , M = 1e5 ;
int n ;
int p[N] , cnt1[N] , cnt2[N] ;
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]) ;
return p[x] ;
}
int main()
{
cin >> n ;
for(int i = 1 ; i <= N - 10 ; i ++) p[i] = i ;
for(int i = 1 ; i <= n ; i ++)
{
int x , y ;
scanf("%d %d",&x , &y) ;
p[find(x)] = find(y + M) ;
}
for(int i = 1 ; i <= M ; i ++) cnt1[find(i)] ++ ;
for(int i = M + 1 ; i <= 2 * M ; i ++) cnt2[find(i)] ++ ;
long long res = 0 ;
for(int i = 1 ; i <= 2 * M ; i ++) res += (long long)cnt1[i] * cnt2[i] ;
cout << res - n ;
return 0 ;
}
版权声明
本文为[ZZXzzx0_0]所创,转载请带上原文链接,感谢
https://blog.csdn.net/yueshehanjiang/article/details/124265582
边栏推荐
- Treatment of incomplete display of listview height
- [record] typeerror: this getOptions is not a function
- std::stoi stol stoul stoll stof stod
- Android Development: the client obtains the latest value in the database in real time and displays it on the interface
- WebView saves the last browsing location
- mysql_linux版本的下載及安裝詳解
- : app: transformclasseswithrobustfordevrease meituan hot repair compilation error record
- 为何PostgreSQL即将超越SQL Server?
- 7、 DOM (Part 2) - chapter after class exercises and answers
- Eight bit binary multiplier VHDL
猜你喜欢

One of the reasons why the WebView web page cannot be opened (and some WebView problem records encountered by myself)

2022.04.23 (the best time for lc_714_to buy and sell stocks, including handling charges)

Esp32 drive encoder -- siq-02fvs3 (vscade + IDF)

ArcMap connecting ArcGIS Server

8266 obtain 18b20 temperature

Partage de la conception de l'alimentation électrique de commutation et illustration des compétences en conception de l'alimentation électrique

The difference between ordinary inner class and static inner class

Switching power supply design sharing and power supply design skills diagram

为何PostgreSQL即将超越SQL Server?
![[advanced level 11 of C language -- character and string functions and their simulation implementation (2)]](/img/47/521bd7f144b0d6a5759d10067c9bea.png)
[advanced level 11 of C language -- character and string functions and their simulation implementation (2)]
随机推荐
Client interns of a large factory share their experience face to face
static类变量快速入门
[报告] Microsoft :Application of deep learning methods in speech enhancement
Practice of Druid SQL and security in meituan review
FTP、ssh远程访问及控制
WebView saves the last browsing location
arcMap 发布切片服务
Installation, use and problem summary of binlog2sql tool
ArcMap连接 arcgis server
12个例子夯实promise基础
[today in history] April 23: the first video uploaded on YouTube; Netease cloud music officially launched; The inventor of digital audio player was born
The fifth bullet of MySQL learning -- detailed explanation of transaction and its operation characteristics
Esp32 (UART ecoh) - serial port echo worm learning (2)
Recyclerview control list item layout match_ Fundamental principle of parent attribute invalidation
ArcGIS JS API dojoconfig configuration
Tencent map and high logo removal method
Redis optimization series (III) solve common problems after master-slave configuration
2022.04.23(LC_763_划分字母区间)
Eight bit binary multiplier VHDL
Switching power supply design sharing and power supply design skills diagram