B. Corner Twist
题目:
思路:
题目大意就是你可以在a这个矩阵里任意选择边大于等于两个格子的矩形,自行选择将两个对角线所在的顶点其中一条对角线顶点+2,另一条+1。这意味着什么呢,意味着不论操作多少次,操作总会使被操作的矩形两行两列都+3,所以(每行每列的总值%3)不会改变,所以我们比较a和b矩阵的(每一行、每一列总值%3)是否发生变化即可。
代码:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve()
{
int x,y;
cin>>x>>y;
vector<int> a(x+1,0),b(y+1,0);
for(int i=1;i<=x;i++)
{
for(int j=1;j<=y;j++)
{
char ans; //要注意题目输入没有空格,用字符型输入
cin>>ans;
a[i]+=ans-'0';
b[j]+=ans-'0';
}
}
for(int i=1;i<=x;i++)
{
for(int j=1;j<=y;j++)
{
char ans;
cin>>ans;
a[i]-=ans-'0'; //相加后相减,只要%3为0即可
b[j]-=ans-'0';
}
}
int flag=1;
for(int i=1;i<=x;i++)
{
if(a[i]%3!=0)
{
flag=0;
break;
}
}
for(int j=1;j<=y;j++)
{
if(b[j]%3!=0)
{
flag=0;
break;
}
}
if(flag)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
cin>>_;
while(_--)
{
solve();
}
return 0;
}
C. Have Your Cake and Eat It Too
题目:
思路:将每个人对每块蛋糕的价值前缀和,后缀和,然后枚举六种情况,abc,acb,bac,bca,cab,cba。用前缀和找出第一个人满足价值需求的最小块数l,用后缀和找出第三个人满足价值需求的最小块数r,剩下的就是第二个人的。每次判断l+1是否小于等于r-1以及该区间是否满足最小价值需求即可。
代码:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=2e5+7;
int a[N],b[N],c[N],a1[N],b1[N],c1[N],a2[N],b2[N],c2[N];
void solve()
{
int n,sum=0;
cin>>n;
a1[0]=0,b1[0]=0,c1[0]=0;
a1[n+1]=0,b1[n+1]=0,c1[n+1]=0;
a2[0]=0,b2[0]=0,c2[0]=0;
a2[n+1]=0,b2[n+1]=0,c2[n+1]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
}
for(int i=1;i<=n;i++)
{
cin>>c[i];
}
//三个数组前缀和
for(int i=1;i<=n;i++)
{
a1[i]=a1[i-1]+a[i];
b1[i]=b1[i-1]+b[i];
c1[i]=c1[i-1]+c[i];
}
//三个数组后缀和
for(int i=n;i>=1;i--)
{
a2[i]=a2[i+1]+a[i];
b2[i]=b2[i+1]+b[i];
c2[i]=c2[i+1]+c[i];
}
//最小价值需求
sum=(a1[n]+2)/3;
//abc
int l=n,r=1;
for(int i=1;i<=n;i++)
{
if(a1[i]>=sum)
{
l=i;
break;
}
}
for(int i=n;i>=1;i--)
{
if(c2[i]>=sum)
{
r=i;
break;
}
}
if(l+1<=r-1 && b1[r-1]-b1[l]>=sum)
{
cout<<1<<' '<<l<<' '<<l+1<<' '<<r-1<<' '<<r<<' '<<n<<endl;
return ;
}
//acb
r=1;
for(int i=n;i>=1;i--)
{
if(b2[i]>=sum)
{
r=i;
break;
}
}
if(l+1<=r-1 && c1[r-1]-c1[l]>=sum)
{
cout<<1<<' '<<l<<' '<<r<<' '<<n<<' '<<l+1<<' '<<r-1<<endl;
return ;
}
//bac
l=n,r=1;
for(int i=1;i<=n;i++)
{
if(b1[i]>=sum)
{
l=i;
break;
}
}
for(int i=n;i>=1;i--)
{
if(c2[i]>=sum)
{
r=i;
break;
}
}
if(l+1<=r-1 && a1[r-1]-a1[l]>=sum)
{
cout<<l+1<<' '<<r-1<<' '<<1<<' '<<l<<' '<<r<<' '<<n<<endl;
return ;
}
//bca
r=1;
for(int i=n;i>=1;i--)
{
if(a2[i]>=sum)
{
r=i;
break;
}
}
if(l+1<=r-1 && c1[r-1]-c1[l]>=sum)
{
cout<<r<<' '<<n<<' '<<1<<' '<<l<<' '<<l+1<<' '<<r-1<<endl;
return ;
}
//cab
l=n,r=1;
for(int i=1;i<=n;i++)
{
if(c1[i]>=sum)
{
l=i;
break;
}
}
for(int i=n;i>=1;i--)
{
if(b2[i]>=sum)
{
r=i;
break;
}
}
if(l+1<=r-1 && a1[r-1]-a1[l]>=sum)
{
cout<<l+1<<' '<<r-1<<' '<<r<<' '<<n<<' '<<1<<' '<<l<<endl;
return ;
}
//cba
r=1;
for(int i=n;i>=1;i--)
{
if(a2[i]>=sum)
{
r=i;
break;
}
}
if(l+1<=r-1 && b1[r-1]-b1[l]>=sum)
{
cout<<r<<' '<<n<<' '<<l+1<<' '<<r-1<<' '<<1<<' '<<l<<endl;
return ;
}
cout<<-1<<endl;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
cin>>_;
while(_--)
{
solve();
}
return 0;
}
D. Swap Dilemma
题目:
思路:
题目要求a选两个坐标互换,而b也选择相同的长度差的任意坐标互换,判断最后两个数组能不能变得一模一样。首先要进行两数组元素的判断,如果元素都不一样肯定不行,在元素一样的基础上呢可以采用逆序对的方法来解决,通过求出两个数组的逆序对数量,判断其奇偶性是否一样就可以判断出能否变成一样的数组了。具体逆序对的内容可以看看这篇算法篇:逆序对-CSDN博客 。
代码:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e5+5;
int a[N],b[N];
int merge_sort(int a[], int l, int mid,int r)
{
int num=0,temp[N],k=l;
int i=l,j=mid+1;
while(i<=mid && j<=r)
{
if(a[i]<=a[j])
{
temp[k++]=a[i++];
}
else
{
temp[k++]=a[j++];
num+=mid-i+1;
}
}
while(i<=mid)
temp[k++]=a[i++];
while(j<=r)
temp[k++]=a[j++];
for(int i=l;i<=r;i++)
{
a[i]=temp[i];
}
return num;
}
int merge(int a[] , int l ,int r)
{
if(l<r)
{
int mid=l+(r-l)/2;
return merge(a,l,mid)+merge(a,mid+1,r)+merge_sort(a,l,mid,r);
}
else
return 0;
}
void solve()
{
map<int , int> mp;
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
cin>>b[i];
mp[b[i]]=i;
}
for(int i=1;i<=n;i++)
{
if(mp.count(a[i])==0)
{
cout<<"No"<<endl;
return ;
}
}
int num1=merge(a,1,n),num2=merge(b,1,n);
if(num1%2==num2%2)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int _=1;
cin>>_;
while(_--)
{
solve();
}
return 0;
}