当前位置:网站首页>2021-2022-2 ACM training team weekly Programming Competition (8) problem solution

2021-2022-2 ACM training team weekly Programming Competition (8) problem solution

2022-04-23 19:16:00 ZZXzzx0_ 0

A. 21 Click game

The question
Here are three numbers A1 , A2 , A3 ,
If A1 + A2 + A3 >= 22 , Output bust
Otherwise output win
Ideas
simulation
Time complexity 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. Palindrome game

The question
Give you a string S,
You can modify S Any character of ,
Ask at least how many times you need to modify , bring S Become a palindrome string .
Ideas
Double pointer
Time complexity 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. A good man or The bad guys ?

The question
Yes n Someone is playing a game ,
The game is like this , We will n Individuals are divided into good people and bad people , May also be n Everyone is good or bad
What good people say must be right , What the bad guys say may be right , Maybe not .
Now let's give you everyone's judgment of others ,
Ask how many good people there are at most
Ideas
be aware n At most 15 personal , Everyone is either good or bad , So violence enumerates all the possibilities , The time complexity is 2 15 2^{15} 215,
You can use it here State compression To enumerate , Or use dfs enumeration .
For each case , everyone Both good and bad people are known .
So what good people say It must be right , If There was a conflict , It means that this situation is not good .
If you can , Just update the number of good people .
Time complexity O ( 2 15 ∗ n 2 ) O(2^{15}*n^{2}) O(215n2)

#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. Exclusive or and

The question
Here you are. n Array of Numbers
a 1 a_1 a1 a 2 a_2 a2 a n a_n an
seek ( ∑ 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=1n1j=i+1n(a[i]a[j])) % ( 1 0 9 10^9 109 + 7)
A ⊕ B A\oplus B AB Express A Exclusive or B , It also means (a ^ b)
Ideas
Bit operation requires Disassemble everyone to see ,
We assume that b [ k ] [ i ] b[k][i] b[k][i] An array of said a i a_i ai The second... Under the binary representation of k k k Is it 1 1 1 still 0 0 0

So we Just find out every bit On ∑ 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=1n1j=i+1n(b[k][i]b[k][j]) Value
The answers add up 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])}} 2ki=1n1j=i+1n(b[k][i]b[k][j]) that will do

Now consider only one 0/1 Array of , How to find ∑ 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=1n1j=i+1n(b[k][i]b[k][j])

Because only 0 / 1 0/1 0/1 Two cases
Even number 1 1 1 Exclusive or equal to 0 0 0
An odd number 1 1 1 Exclusive or equal to 1 1 1

therefore
∑ i = 1 n − 1 ∑ j = i + 1 n ( b [ k ] [ i ] ⊕ b [ k ] [ j ] ) = 1 Of individual Count ∗ 0 Of individual Count \sum_{i=1}^{n - 1}{\sum_{j=i + 1}^{n}{(b[k][i] \oplus b[k][j])}}=1 The number of *0 The number of i=1n1j=i+1n(b[k][i]b[k][j])=1 Of individual Count 0 Of individual Count

Time complexity 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. Eat food

The question
Yes n Dish , Each dish needs a i a_i ai Time to eat , Yes b i b_i bi Delicious degree of .
Now there are the following rules :

  • After ordering a dish , You can only order a dish after you finish it .
  • t You can't order after the moment , But you can still eat vegetables .
  • Each dish can only be ordered once .

Finally, what is the most delicious food you can get .
Ideas
If Don't consider Second rule , It's obviously a 01 knapsack problem ,
We assume that f [ j ] f[j] f[j] The time is j j j Maximum delicacy in the case of ,
f [ j ] = f [ j − a [ i ] ] + b [ i ] f[j] = f[j - a[i]] + b[i] f[j]=f[ja[i]]+b[i]

Now? consider Add the second rule ,
That means we can stay i < t i < t i<t At any moment of the day, add b i b_i bi,

obviously need Yes a i a_i ai Sort from small to large , because Eating at the end of a long time is the most profitable .

Time complexity 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: rectangular

The question
Given n A point in a coordinate system ( x i x_i xi, y i y_i yi)
If there are three points as shown in the figure below ( Black spot ) You can construct a new point ( Red dot ). Find the maximum number of constructable points .
 Insert picture description here

Ideas
A place that can be operated as long as it is a connected area , You can fill this area with dots .
 Insert picture description here
Blue is the existing dot , Red is the point added later , You can add in a little bit .
As long as you're in this area , All points on the line can be filled in .
Find the... In each block , Number of horizontal and vertical lines at all points , Multiplication is all points .

How to find how many areas there are ? We can use and search the set , Tie the abscissa and ordinate of each point into a set , In this way, those with the same vertical line and the same horizontal line will be tied in , Form a large collection , But when calculated separately , Only the vertical and horizontal lines are calculated separately .
Finally, subtract the existing points .
Time complexity 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://yzsam.com/2022/04/202204231912032543.html