Codeforces1602C,546C,1520E,277A

1602C. Array Elimination (logical operation &)

Meaning:

Given a group of numbers, for a number k, K positions can be selected for several operations at a time: the number at k positions minus the sum of the K numbers.
Find all the numbers k that can make this group of numbers become 0.

Idea:

To change all numbers to 0, that is, to change the digits of all numbers to 0.
Each operation subtracts the sum of k numbers. Therefore, in order to change a digit to 0, the digit of the subtracted and value should also be 0.
In order to make the digit of the value 0, the digit of the selected k positions is 1.

Because it can be operated several times, for x 1s of a column of digits, the factor y 1s of x can be selected, which can convert the digits of y numbers to 0, and then operate several times.

Considering all the digits, then the k satisfying the condition is all the common divisors of 1 of the 30 digits.

One digit of a number is 1. Subtract a number whose digit is also 1, and the digit becomes 0. The digits do not affect each other.

Find all divisors of a group of numbers = = find all factors of gcd.

For such a bit operation problem, we should not look at the whole number, but the operation and change between each digit.

Code:

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

void pd(int x)
{
	for(int i=0;i<=30;i++)
	{
		if(x&(1<<i)) f[i]++;
	}
}

void prim(int x)
{
	int cnt=0;
	for(int i=1;i<=x/i;i++)
	{
		if(x%i==0){
			ans[++cnt]=i;
			if(x/i!=i) ans[++cnt]=x/i;
		}
	}
	sort(ans+1,ans+cnt+1);
	
	for(int i=1;i<=cnt;i++) cout<<ans[i]<<" ";
	cout<<endl;
} 

int main(){
	Ios;
	
	cin>>T;
	while(T--)
	{
		cin>>n;
		
		mem(f,0);
		for(int i=1;i<=n;i++){
			int x;cin>>x;
			pd(x);
		}
		
		int g;
		for(int i=0;i<=30;i++){
			if(i==0) g=f[i];
			else g=__gcd(g,f[i]);
		}
		
		if(!g) for(int i=1;i<=n;i++) cout<<i<<" ";
		prim(g);
	}
	
	return 0;
}

546.C. Soldier and Cards (simulation)

Meaning:

Two people play card games. Each person has a pile of cards, one at a time from the top of the pile.
For the larger one, put the opponent's cards at the bottom of the pile first, and then put your own cards at the bottom of the pile. Those without a license lose.
Q. if the outcome can be determined, the number of innings and the winner will be output; Otherwise, output - 1.

Idea:

Queue simulation.
How to judge whether there is a final solution?
You can use string to record the state, and then judge whether the current two states have appeared before.
The number of cycles can also be determined.

Code:

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

//Handwriting queue, mark status
int main()
{
	Ios;
	
	int s;cin>>s;
	
	int h1=0,t1=-1,h2=0,t2=-1;
	cin>>n;
	for(int i=1;i<=n;i++){
		int x;cin>>x;
		que1[++t1]=x;
	}
	cin>>m;
	for(int i=1;i<=m;i++){
		int x;cin>>x;
		que2[++t2]=x;
	}
	
	int flag=0,cnt=0;
	while(1)
	{
		cnt++;
		int x=que1[h1];h1++;
		int y=que2[h2];h2++;
		
		if(x>y) que1[++t1]=y,que1[++t1]=x;
		else que2[++t2]=x,que2[++t2]=y;
		
		string s1,s2;
		for(int i=h1;i<=t1;i++){
			s1+=(char)(que1[i]+'0');
		}
		for(int i=h2;i<=t2;i++){
			s2+=(char)(que2[i]+'0');
		}
		if(mp[{s1,s2}]) break;
		else mp[{s1,s2}]=1;
		
		if(t1<h1||t2<h2){
			if(t1<h1) flag=2;
			else flag=1;
			break;
		}
	}
	
	if(flag){
		cout<<cnt<<" "<<flag;
	}
	else cout<<-1;
}

//stl, judge the number of cycles
int main(){
	Ios;
	
	int s;cin>>s;
	cin>>n;
	
	queue<int> que1,que2;
	
	for(int i=1;i<=n;i++){
		int x;cin>>x;
		que1.push(x);
	}
	
	cin>>m;
	for(int i=1;i<=m;i++){
		int x;cin>>x;
		que2.push(x);
	}
	
	int flag=0,cnt=0;
	while(1)
	{
		cnt++;
		int x=que1.front();que1.pop();
		int y=que2.front();que2.pop();
		
		if(x>y) que1.push(y),que1.push(x);
		else que2.push(x),que2.push(y);
		
		if(!que1.size()||!que2.size()){
			if(!que1.size()) flag=2;
			else flag=1;
			break;
		}
		else if(cnt>=10000000) break;
	}
	
	if(flag){
		cout<<cnt<<" "<<flag;
	}
	else cout<<-1;
	
	return 0;
}

1520. E. arranging the sheet

Meaning:

Give n positions, each of which is empty or has sheep.
You can move the sheep to the left or right every time, and the moving position needs to be empty.
Q. how many times do you move at least and all the sheep get together (adjacent)?

Idea:

And what I've done before The soldiers stood in line The same idea. It's a simplification of the problem.

Set the final starting sheep position as x, then the following sheep positions are x + 1 , x + 2 , x + 3... x+1,x+2,x+3... x+1,x+2,x+3...
Then, the number of times a sheep with position ai needs to move to its final position is: ∣ x + i − 1 − a i ∣ |x+i-1 - ai| ∣x+i−1−ai∣;
We know that the minimum sum of absolute values is the median:
If make ∣ x − a i ∣ + ∣ x − a i + 1 ∣ + ∣ x − a i + 2 ∣ + . . . + ∣ x − a i + n ∣ |x-a_i| + |x-a_{i+1}| + |x-a_{i+2}| +...+ |x-a_{i+n}| ∣ x − ai ∣ + ∣ x − ai+1 ∣ + ∣ x − ai+2 ∣ +... + ∣ x − ai+n ∣ is the smallest, and X should take the median of ai.
Here is also the minimum value of the addition of absolute values, so we can turn it into the above formula: ∣ x − ( a i − i + 1 ) ∣ |x - (ai-i+1)| ∣x−(ai−i+1)∣.
Therefore, the value of the starting position x is the median of the array {ai-i+1}.

For array {a}, the number of bits is ordered a[n/2+1].

Code:

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

int main(){
	Ios;
	
	cin>>T;
	while(T--)
	{
		cin>>n;
		int cnt=0;
		for(int i=1;i<=n;i++){
			char c;cin>>c;
			if(c=='*') a[++cnt]=i;
		}
		
		for(int i=1;i<=cnt;i++){
			a[i]-=i-1;
		}
		
		ll st=a[cnt/2+1],ans=0;
		
		for(int i=1;i<=cnt;i++){
			ans+=abs(a[i]-st);
		}
		cout<<ans<<endl;
	}
	
	return 0;
}

277.A. Learning Languages

Meaning:

A total of n people, m languages. Each person has 0~m languages. Each person spends 1 for each language they learn.
Ask, how much is the minimum cost, so that everyone can communicate unimpeded. (everyone can communicate with other n-1 people)

Idea:

Merge people in all the same languages. In this way, everyone is divided into several collections.

For each person, traverse all others:
If two people are not in the same set, they spend 1 to learn each other's language, so that the two sets are merged.

Finally, we have to make a special judgment. If the number of languages mastered by everyone is 0, n is output.

Code:

const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
vector<int> v[N];
int pre[N];

int find(int x){
	int t=x;
	while(pre[x]!=x) x=pre[x];
	pre[t]=x;
	return x;
}

int main(){
	Ios;
	
	cin>>n>>m;
	
	int flag=0;
	for(int i=1;i<=n;i++)
	{
		pre[i]=i;
		int k;cin>>k;
		if(k) flag=1;
		for(int j=1;j<=k;j++){
			int x;cin>>x;
			v[x].push_back(i);
		} 
	}
	
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<v[i].size();j++)
		{
			pre[find(v[i][j])]=pre[find(v[i][j-1])];
		}
	}
	
	int cnt=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
		{
			if(find(i)!=find(j))
				cnt++,pre[find(i)]=find(j);
		}
	}
	
	if(!flag) cout<<n;
	else cout<<cnt;
	
	return 0;
}

Posted on Tue, 26 Oct 2021 10:18:21 -0400 by samscripts