CF1400: 1463B (structure, thinking), 1303B (binary answer), 977D (map, search)

1463.B. Find The Array

Meaning:

Give the sequence a, the sum of which is S.
To construct a sequence b, its adjacent terms can be divided by each other, and the sum of | AI Bi | does not exceed S/2.

Idea:

Two ideas.
Idea 1:
Let the sum of odd positions of a sequence be S odd and the sum of even positions be S even. Then, S odd + S even = S.
At the same time, at least one of s odd and s even is not more than S/2. (to the contrary, if both exceed, the sum of the two exceeds s)
We construct all numbers in this position (odd or even) in sequence b as 1 and other positions as ai.
Firstly, the two terms of adjacent positions can be divided by each other.
Secondly, the sum of | AI Bi | of this position (odd / even position) does not exceed S/2, and the sum of | AI Bi | of another position is 0. The sum shall not exceed S/2.

Idea 2:
Each number bi of the b sequence is constructed as the highest idempotent of 2 that does not exceed the corresponding position ai.
In this way, the value of | ai Bi | of each position does not exceed half of ai, and the sum of | ai Bi | of all positions does not exceed S/2.

Code:

const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];

//Idea 2:
int main(){
	Ios;
	
	cin>>T;
	while(T--)
	{
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			int x;cin>>x;
			int p=log(x)/log(2);
			cout<<(ll)pow(2,p)<<" ";
		}
		cout<<endl;
	}
	
	return 0;
}

//Idea 1:
int main(){
	Ios;
	
	cin>>T;
	while(T--)
	{
		cin>>n;
		
		ll sum1=0,sum2=0,sum=0;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			if(i%2) sum1+=a[i];
			else sum2+=a[i];
			sum+=a[i];
		}
		
		if(sum2<=sum/2)
		{
			for(int i=1;i<=n;i++)
			{
				if(i%2) cout<<a[i]<<" ";
				else cout<<1<<" ";
			}
		}
		else
		{
			for(int i=1;i<=n;i++)
			{
				if(i%2) cout<<1<<" ";
				else  cout<<a[i]<<" ";
			}
		}
		cout<<endl;
	}
	
	return 0;
}

Experience:

In the future, when we encounter the problem of mutual division, we should think about the power of 2. For any two powers of 2, they can be divided by each other.
1 and any other number are also possible.

In addition, at least one of s odd and s even is not more than S/2.

1303B. National Project (two point answer)

Meaning:

There is a highway with a length of n km to be constructed, 1 km per day.
There are two kinds of weather, good weather x days and bad weather y days, which appear in turn. During the construction of this n kilometer, the number of days with good weather shall not be less than half.
Q: how much time will it take to complete the construction?

Idea:

It is difficult to find the minimum time, but for a given time, we can judge whether it is satisfied.
Judge whether the given x days are satisfied: whether the number of good weather days + available bad weather days in the current x days exceeds n.
So you can split the answer.

The available bad weather days are: min (total bad weather days, n/2).

Code:

const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int x,y;

bool check(int mid)
{
	int q=mid/(x+y);
	int left=mid%(x+y);
	
	int t=q*x+min(left,x);
	int t1=min(n/2,q*y+max(0ll,left-x));
	
	return t+t1>=n;
}

signed main(){
	Ios;
	
	cin>>T;
	while(T--)
	{
		cin>>n>>x>>y;
		
		int l=n,r=1e18;
		while(l<r)
		{
			int mid=l+r>>1;
			
			if(check(mid)) r=mid;
			else l=mid+1;
		}
		cout<<l<<endl;
	}
	
	return 0;
}

Experience:

I thought I had mastered the binary answer well, but I still didn't remember when I saw this question..
In the future, we should think more divergent. When we can't do it, we should think about whether these algorithms can be used.

977D. Divide by three, multiply by two (map + burst search)

Meaning:

A sequence a with length n is given, and the rearrangement meeting the following requirements is output. (n≤100)
Requirement: the latter number is divided by 3 or twice the former number.

Idea:

map records whether each number exists.
Just search.

Code:

const int N = 200010, mod = 1e9+7;
ll T, n, m, a[N];
ll f[N];

void dfs(int u)
{
	if(u==n+1){
		for(int i=1;i<=n;i++) cout<<f[i]<<" ";
		return;
	}
	if(f[u-1]%3==0&&mp[f[u-1]/3]){
		f[u]=f[u-1]/3;
		dfs(u+1);
	}
	
	if(mp[f[u-1]*2]){
		f[u]=f[u-1]*2;
		dfs(u+1);
	}
}

int main(){
	Ios;
	
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],mp[a[i]]++;
	
	for(int i=1;i<=n;i++)
	{
		f[1]=a[i];
		dfs(2);
	}
	
	return 0;
}

Very good.

Posted on Wed, 27 Oct 2021 11:52:34 -0400 by ehmer