A. Image
simulation
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
int main()
{
int T;cin>>T;
while(T--){
mp.clear();char a,b,c,d;cin>>a>>b>>c>>d;
mp[a]++;mp[b]++;mp[c]++;mp[d]++;
int sum=0;int r=4;
for (auto i:mp){
if(i.second==1&&r!=1){sum++;r--;}
if(i.second==2&&r!=2){sum++;r-=2;}
}
cout<<sum<<endl;
}
return 0;
}
The problem solution is done with set, which is simpler
#include<bits/stdc++.h>
using namespace std;
set<char>mp;
int main()
{
int T;cin>>T;
while(T--){
mp.clear();
char a,b,c,d;cin>>a>>b>>c>>d;
mp.insert(a);mp.insert(b);mp.insert(c);mp.insert(d);
cout<<(int)mp.size()-1<<endl;
}
return 0;
}
B. Deadly Laser
Idea: First of all, no matter how you go, the minimum number of steps is n+m-2, so it depends on the range covered by the laser blocking the road
There are 4 blocking methods
1. Block the lower left corner 2. Block the upper right corner 3. Block the vertical 4. Block the horizontal
code:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;cin>>T;
while(T--){
int n,m,sx,sy,d;cin>>n>>m>>sx>>sy>>d;
if(m-sy<=d&&n-sx<=d||sy-1<=d&&sx-1<=d||sy-1<=d&&m-sy<=d||sx-1<=d&&n-sx<=d)
cout<<-1<<'\n';
else cout<<(n+m-2)<<'\n';
}
return 0;
}
C. Min-Max Array Transformation
Note: the data range is 2e5, and the array will be TLE if it is too small
Ideas:
First of all, it is easy to find the smallest array, just find the number that is exactly equal to it;
To find the largest number, look at the rules of the sample. From n-1 to 0, if a[i] is greater than b[i-1], it means that b[i-1] cannot be a[i] and before The sum of numbers, so start from b[i-1] as the new beginning; otherwise, because the previous b[i] is greater than a[i], there is no limit, so you can choose the largest
#include<bits/stdc++.h>
using namespace std;
int a[200005],b[200005],d[200005];
int main()
{
ios::sync_with_stdio(0);
int T;cin>>T;
while(T--){
int n;cin>>n;
int minn=999999999;int maxx=0;
for(int i=0;i<n;i++)cin>>a[i];for(int i=0;i<n;i++)cin>>b[i];
int l=0;
for(int i=0;i<n;i++){while(b[l]<a[i])l++;cout<<b[l]-a[i]<<" ";}
cout<<'\n';
l=n-1;
for(int i=n-1;i>=0;i--){d[i]=b[l]-a[i];if(a[i]>b[i-1])l=i-1;}
for(int i=0;i<n;i++)cout<<d[i]<<" ";cout<<'\n';
}
return 0;
}
Finding the truth from the front to the back is almost the same
#include<bits/stdc++.h>
using namespace std;
int a[200005],b[200005];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);
int T;cin>>T;
while(T--){
int n;cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n;i++)cin>>b[i];
int l=0;
for(int i=0;i<n;i++){while(b[l]<a[i])l++;cout<<b[l]-a[i]<<" ";}
cout<<'\n';l=0;
for(int i=0;i<n;i++){
l=max(l,i);while(a[l+1]<=b[l]&&l+1<n)l++;cout<<b[l]-a[i]<<" ";
}
cout<<'\n';
}
return 0;
}
D. Maximum AND
Title: There are arrays a and b, the array c is obtained by XORing a and b, and the final value is the AND operation of the array c, find the largest value
Ideas:
method one:
It is known that the highest bit of the last value must be the position of 1 in each of the c arrays
Each position with 1 is made of 1 of array a and 0 of array b (or 0 of array a and 0 of array b)
Then you can set a number x, x and each a[i] above, and the result cc can only be displayed if there are 1 digits on x and a[i] have 1 digits at the same time
x and each of the above (inverted b[i]), the result dd is that only the digits with 1 on x and the digits with 1 at the same time (inverted b[i]) can be displayed
If cc and dd can be equal one-to-one, it means that the 1 of a[i] and the 0 of b[i] can correspond one-to-one (it is also the one-to-one correspondence between the 0 of a[i] and the 1 of b[i])
So when checking, you only need to judge whether cc and dd are equal.
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[100005];int b[100005];int n;
int c[100005];int d[100005];
bool check(int x){
for(int i=1;i<=n;i++)c[i]=a[i]&x;
for(int i=1;i<=n;i++)d[i]=(~b[i])&x;
sort(c+1,c+1+n);sort(d+1,d+1+n);
for(int i=1;i<=n;i++){
if(c[i]!=d[i])return 0;
}
return 1;
}
signed main()
{
int T;cin>>T;
while(T--){
int coun=0;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
int res=0;
for(int i=31;i>=0;i--){
if(check(res|(1<<i)))res=res|((1<<i));
}
cout<<res<<'\n';
}
return 0;
}
Method 2 (and search)
If the 1 part of a certain bit is paired with the 0 part of b, if the number is wrong, continue
If it is correct, match the 1 part of a with the 0 part of b from that part, if the number is wrong, then continue
But I haven't watched it yet...