Codeforces Round #742 div.2 A-F problem solution

Video Explanation: TBD

A. Domino Disaster

General idea of the topic

There is one 2 × n   ( 1 ≤ n ≤ 100 ) 2\times n~(1 \leq n \leq 100) two × n  ( 1 ≤ n ≤ 100), with 1 × 2 1\times 2 one × Each domino is placed vertically or horizontally, and each grid is covered by at most one domino.

Now, given the grid of one row, find out what the other row looks like.

Problem solution

'L' and 'R' remain unchanged,'D 'and' U 'are interchanged.

Reference code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

int main()
{
	int T,n,i;
	string s;
	cin>>T;
	while(T--)
	{
		cin>>n;
		cin>>s;
		for(i=0;i<n;i++)
		{
			if(s[i]=='U')
				s[i]='D';
			else if(s[i]=='D')
				s[i]='U';
		}
		cout<<s<<endl;
	}
}

B. MEXor Mixup

General idea of the topic

Given two integers a , b   ( a > 0 , b ≥ 0 ) a,b~(a>0,b \geq 0) a,b  ( a> 0, B ≥ 0), find the smallest nonnegative integer array size, so that M E X MEX The MEX value is a a a , X O R XOR XOR value is b b b .

Problem solution

set up 0 0 0 to i i The XOR sum of i is p r e i pre_i prei​ . There are several situations:

  • if p r e a − 1 = b pre_{a-1}=b prea − 1 = b, the array is 0 0 0 to a − 1 a-1 a − 1 is enough, and the answer is a a a ;
  • if p r e a − 1 ≠ b , p r e a − 1 ⊕ a = b pre_{a-1}\neq b,pre_{a-1}\oplus a=b prea − 1  = b,prea − 1 ⊕ a=b, then the array is 0 0 0 to a − 1 a-1 a − 1, add any two greater than a a Elements of a x , y x,y x. Y, satisfied x ⊕ y = a ⊕ b x\oplus y=a\oplus b x ⊕ y=a ⊕ b, the answer is a + 2 a+2 a+2 ;
  • if p r e a − 1 ≠ b , p r e a − 1 ⊕ a ≠ b pre_{a-1}\neq b,pre_{a-1}\oplus a \neq b prea − 1  = b,prea − 1 ⊕ a  = b, then the array is 0 0 0 to a − 1 a-1 a − 1, add an element a ⊕ b a\oplus b a ⊕ b is enough, and the answer is a + 1 a+1 a+1 ;

Reference code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

const int MAXN=300300;
int pre[MAXN];

int main()
{
	int T,a,b,i,c,ans;
	for(i=1;i<MAXN;i++)
		pre[i]=pre[i-1]^i;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&a,&b);
		c=pre[a-1]^b;
		if(c==0)
			ans=a;
		else if(c==a)
			ans=a+2;
		else
			ans=a+1;
		printf("%d\n",ans);
	}
}

C. Carrying Conundrum

General idea of the topic

Someone made a wrong carry when calculating decimal addition. Originally, if the current bit is greater than 10 10 10 carries to the first place on the left, and the result is wrong to carry to the second place on the left.

given n   ( 1 ≤ n ≤ 1 0 9 ) n~(1 \leq n \leq 10^9) n  ( 1 ≤ n ≤ 109), find the number of positive integer pairs ( a , b ) (a,b) (a,b) satisfy that under the addition of wrong carry, the sum is n n n .

Problem solution

It will be found that the operations of odd and even digits are independent of each other, so you can directly split them and calculate the results separately.
Set the odd digits extracted as a a a. Even digits are extracted as b b b. The answer to a nonnegative integer pair is ( a + 1 ) ⋅ ( b + 1 ) (a+1)\cdot(b+1) (a+1) ⋅ (b+1), and then subtract the existing 0 0 0, so the answer is ( a + 1 ) ( b + 1 ) − 2 (a+1)(b+1)-2 (a+1)(b+1)−2 .

Reference code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

int main()
{
	ll T,n,a,b,i,j,ans;
	scanf("%lld",&T);
	while(T--)
	{
		scanf("%lld",&n);
		a=b=0;
		for(i=1,j=1;i<=n;i*=100,j*=10)
			a+=n/i%10*j;
		for(i=10,j=1;i<=n;i*=100,j*=10)
			b+=n/i%10*j;
		ans=(a+1)*(b+1)-2;
		printf("%lld\n",ans);
	}
}

D. Expression Evaluation Error

General idea of the topic

yes n ( 1 ≤ n ≤ min ⁡ ( 100 , s ) ) n(1 \leq n \leq \min(100,s)) n(1 ≤ n ≤ min(100,s)) decimal positive integers, the sum of which is s ( 1 ≤ s ≤ 1 0 9 ) s(1 \leq s \leq 10^9) s(1≤s≤109) . Someone put this n n n numbers are regarded as 11 base numbers. Find this n n When the number of n is, it will get the maximum result according to the sum of binary 11.

Problem solution

If it exists in decimal system 1 0 k 10^k 10k, then its value in hexadecimal is 1 1 k 11^k 11k . If assigned to 10 10 10 numbers, then the sum is 10 × 1 1 k − 1 10\times 11^{k-1} ten × 11k − 1, obviously smaller.

Therefore, we get the greedy strategy: if n = a 1 a 2 . . . a k ‾ n=\overline{a_1a_2...a_k} n=a1, a2... ak, then it is decomposed into a 1 a_1 a1 1 ⋅ 1 0 k − 1 1\cdot 10^{k-1} 1⋅10k−1 , a 2 a_2 a2 1 ⋅ 1 0 k − 2 1\cdot 10^{k-2} 1⋅10k−2 ,..., a k a_k ak , PCs 1 1 1 optimal. If the quantity exceeds n n n, then merge them in any way, and the answer remains unchanged. If the quantity is insufficient n n n, the smaller number will be preferentially divided into several 1 1 1. Minimum loss.

When implementing, you might as well set each number to 1 1 1, and then modify it one by one as 1 0 x 10^x 10x, where x x x is as large as possible. If there is more, it can be merged into any element.

Reference code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

const int MAX=1e9;

int main()
{
	int T,s,n,i,j,a[110];
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&s,&n);
		for(i=1;i<=n;i++)
			a[i]=1;
		s-=n;
		for(i=MAX;i>=1;i/=10)
		{
			for(j=1;s>=i-1&&j<=n;j++)
			{
				if(a[j]>1)
					continue;
				a[j]+=i-1;
				s-=i-1;
			}
		}
		a[1]+=s;
		for(i=1;i<=n;i++)
			printf("%d%c",a[i],i==n?'\n':' ');
	}
}

E. Non-Decreasing Dilemma

General idea of the topic

There is a length of n   ( 1 ≤ n ≤ 2 ⋅ 1 0 5 ) n~(1 \leq n \leq 2 \cdot 10^5) n  ( Array of 1 ≤ n ≤ 2 ⋅ 105) a   ( 1 ≤ a i ≤ 1 0 9 ) a~(1 \leq a_i \leq 10^9) a  ( 1 ≤ ai ≤ 109), in the following two forms: q   ( 1 ≤ q ≤ 2 ⋅ 1 0 5 ) q~(1 \leq q \leq 2 \cdot 10^5) q  ( 1 ≤ Q ≤ 2 ⋅ 105) inquiries:

  • 1    x    y 1\;x\;y 1xy - will a x ( 1 ≤ x ≤ n ) a_x (1 \leq x \leq n) ax (1 ≤ x ≤ n) is modified as y   ( 1 ≤ y ≤ 1 0 9 ) y~(1 \leq y \leq 10^9) y (1≤y≤109) ;
  • 2    l    r 2\;l\;r 2lr - find [ a l , a l + 1 , . . . , a r ] [a_l,a_{l+1},...,a_r] In [al, al+1,..., ar], how many continuous non falling intervals, that is, how many pairs ( p , q ) (p,q) (p,q) satisfied l ≤ p ≤ q ≤ r l\leq p \leq q \leq r l ≤ p ≤ q ≤ r and a p ≤ a p + 1 ≤ . . . ≤ a q a_{p} \leq a_{p+1}\leq ... \leq a_q ap​≤ap+1​≤...≤aq​ ;

Problem solution

Interval merging line segment tree template problem.

Reference code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

#define lson i<<1
#define rson i<<1|1

const int MAXN=200200;
int a[MAXN];

struct Seg
{
	int l,r;
	ll ans,llen,rlen;
}seg[MAXN<<2];

Seg merge(Seg s1,Seg s2)
{
	Seg ret;
	ret.ans=s1.ans+s2.ans;
	ret.l=s1.l; ret.r=s2.r;
	if(s1.llen==s1.r-s1.l+1&&a[s1.r]<=a[s2.l])
		ret.llen=s1.llen+s2.llen;
	else
		ret.llen=s1.llen;
	
	if(s2.r-s2.l+1==s2.rlen&&a[s1.r]<=a[s2.l])
		ret.rlen=s1.rlen+s2.rlen;
	else
		ret.rlen=s2.rlen;
		
	if(a[s1.r]<=a[s2.l])
		ret.ans+=s1.rlen*s2.llen;
	return ret;
}

void pushUp(int i)
{
	seg[i]=merge(seg[lson],seg[rson]);
}

void build(int i,int l,int r)
{
	if(l==r)
	{
		seg[i].l=seg[i].r=l;
		seg[i].llen=seg[i].rlen=1;
		seg[i].ans=1;
		return;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushUp(i);
}

void change(int i,int x)
{
	if(seg[i].l==seg[i].r)
	{
		return;
	}
	int mid=(seg[i].l+seg[i].r)>>1;
	if(x<=mid)
		change(lson,x);
	else
		change(rson,x);
	pushUp(i);
}

Seg query(int i,int l,int r)
{
	if(seg[i].l==l&&seg[i].r==r)
	{
		return seg[i];
	}
	int mid=(seg[i].l+seg[i].r)>>1;
	if(r<=mid)
		return query(lson,l,r);
	else if(l>=mid+1)
		return query(rson,l,r);
	else
		return merge(query(lson,l,mid),query(rson,mid+1,r));
}

int main()
{
	int n,q,i,op,x,y;
	scanf("%d%d",&n,&q);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
	build(1,1,n);
	while(q--)
	{
		scanf("%d%d%d",&op,&x,&y);
		if(op==1)
		{
			a[x]=y;
			change(1,x); 
		}
		else
		{
			printf("%lld\n",query(1,x,y).ans);
		}
	}
}

F. One-Four Overload

General idea of the topic

There is one n × m   ( 1 ≤ n , m ≤ 500 ) n\times m~(1 \leq n,m \leq 500) n × m  ( 1 ≤ n,m ≤ 500), in which some lattices are marked, and there is no marked lattice adjacent to the edge of the grid (the adjacency of this question refers to four neighborhoods).

Now you need to fill in each grid according to the following rules:

  • Each unlabeled cell contains a number of 1 1 1 or 4 4 4 ;
  • The number contained in each marked grid is the sum of the numbers contained in all its adjacent grids;
  • The number contained in each marked grid is 5 5 Multiples of 5;

Find such a grid filling scheme that meets the conditions. If it does not exist, no solution will be output.

Problem solution

For ease of description, the marked grid is called X and the unmarked grid is called Y.
It is easy to get that the number contained in X must be 5 5 5 or 10 10 10. If the number of Y adjacent to X is odd, it is illegal.

In a legal case, each x must be on a ring. That is, Y is divided into several connected blocks by X.

  • For transversely continuous X, ensure that the upper and lower Y are different.
  • For longitudinally continuous X, ensure that the left and right Y are different.
  • For the X at the corner, ensure that the two Y on the outside are different.
  • For a single X, make sure it has two 1 1 1 and 2 4 4 4 .

To sum up, we can construct as follows:
From top to bottom, from left to right 1 , 4 1,4 1,4 fill in the numbers alternately, so as to ensure the validity of X for individual X and corner X.
If both the current grid and the previous grid are X, it will be modified 1 , 4 1,4 1,4 alternating order. In this way, the longitudinal continuous x can be guaranteed to be legal, and because the upper and lower y of the transverse continuous X are not connected with each other and there are no odd number of Y adjacent x, it is also legal.

Reference code

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

const int MAXN=550;
int g[2][4]={{-1,0,0,1},{0,-1,1,0}};
char mz[MAXN][MAXN];
int ans[MAXN][MAXN];

int main()
{
	int n,m,i,j,k,flag,cnt;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
		scanf("%s",mz[i]+1);
	flag=1;
	for(i=1;i<=n&&flag;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(mz[i][j]=='X')
			{
				cnt=0;
				for(k=0;k<4;k++)
				{
					if(mz[i+g[0][k]][j+g[1][k]]=='.')
						cnt++;
				}
				if(cnt&1)
				{
					flag=0;
					break;
				}
				ans[i][j]=cnt/2*5;
			}
		}
	}
	if(!flag)
	{
		printf("NO\n");
	}
	else
	{
		printf("YES\n");
		for(i=1,k=1;i<=n;i++,k=5-k)
		{
			for(j=1;j<=m;j++)
			{
				if(mz[i][j]=='.')
					ans[i][j]=k;
				else if(mz[i-1][j]=='X')
					k=5-k;
			}
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=m;j++)
				printf("%d ",ans[i][j]);
			puts(""); 
		}
	}
}

Tags: C Algorithm

Posted on Tue, 07 Sep 2021 21:32:04 -0400 by charlesg