A. Array Divisibility
题目类型:构造。
解题思路:每个数都是自己因数的倍数,所以直接构造a[i]=i。
AC代码:
#include<iostream>
using namespace std;
void solve()
{
int n;cin>>n;
for(int i=1;i<=n;i++){
cout<<i<<' ';
}
cout<<'\n';
}
int main()
{
int t;cin>>t;
while(t--){
solve();
}
return 0;
}
B. Corner Twist
题目类型:构造,贪心。
解题思路:(暴力)从左上向右下(不含右边界和下边界)遍历,取正方形四个对角为a[i][j],a[i][j+1],a[i+1][j],a[i+1][j+1],贪心的将每个a[i][j]变成b[i][j]。最后遍历右边界和下边界,若a[i][j]!=b[i][j]则输出"NO"。
AC代码:
#include<iostream>
using namespace std;
const int N=510;
char a[N][N],b[N][N];
void solve(){
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%s",a[i]+1);
}
for(int i=1;i<=n;i++){
scanf("%s",b[i]+1);
}
//贪心
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
if(a[i][j]!=b[i][j]){
int k=(b[i][j]-a[i][j]+3)%3;
a[i][j]=(a[i][j]-'0'+k)%3+'0';
a[i+1][j+1]=(a[i+1][j+1]-'0'+k)%3+'0';
a[i+1][j]=(a[i+1][j]-'0'+3-k)%3+'0';
a[i][j+1]=(a[i][j+1]-'0'+3-k)%3+'0';
}
}
}
//检验右边界和下边界
for(int i=1;i<=n;i++){
if(a[i][m]!=b[i][m]){
cout<<"NO\n";
return;
}
}
for(int i=1;i<=m;i++){
if(a[n][i]!=b[n][i]){
cout<<"NO\n";
return;
}
}
cout<<"YES\n";
}
int main()
{
int t;cin>>t;
while(t--){
solve();
}
return 0;
}
C. Have Your Cake and Eat It Too
题目类型:贪心,前缀和,暴力。
解题思路:
1.求出a,b,c三个数组的前缀和与后缀和,以及t=。
2.分类讨论(条件成立则输出答案)
①左分界点为a的前缀和大于t,右分界点为b的后缀和大于t,判断左右分界点之间c数组元素之和是否大于t;
②左分界点为a的前缀和大于t,右分界点为c的后缀和大于t,判断左右分界点之间b数组元素之和是否大于t;
③左分界点为b的前缀和大于t,右分界点为a的后缀和大于t,判断左右分界点之间c数组元素之和是否大于t;
④左分界点为b的前缀和大于t,右分界点为c的后缀和大于t,判断左右分界点之间a数组元素之和是否大于t;
⑤左分界点为c的前缀和大于t,右分界点为a的后缀和大于t,判断左右分界点之间b数组元素之和是否大于t;
⑥左分界点为c的前缀和大于t,右分界点为b的后缀和大于t,判断左右分界点之间a数组元素之和是否大于t。
3.都不成立则输出-1。
AC代码:
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=200010;
int a[N],b[N],c[N];
//前缀和
LL pa[N],pb[N],pc[N];
//后缀和
LL sa[N],sb[N],sc[N];
//整除3向上取整
LL divup(LL x){
if(x%3==0){
return x/3;
}
else{
return x/3+1;
}
}
void solve(){
int n;cin>>n;
//初始化后缀和数组防止上一组数据干扰
memset(sa,0,sizeof sa);
memset(sb,0,sizeof sb);
memset(sc,0,sizeof sc);
//求前缀和 and 后缀和
for(int i=1;i<=n;i++){
cin>>a[i];
pa[i]=pa[i-1]+a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
pb[i]=pb[i-1]+b[i];
}
for(int i=1;i<=n;i++){
cin>>c[i];
pc[i]=pc[i-1]+c[i];
}
for(int i=n;i>=1;i--){
sa[i]=sa[i+1]+a[i];
}
for(int i=n;i>=1;i--){
sb[i]=sb[i+1]+b[i];
}
for(int i=n;i>=1;i--){
sc[i]=sc[i+1]+c[i];
}
//求tot/3
LL t=divup(pa[n]);
bool f1=1,f2=1,f3=1;
//分类讨论分界点情况
for(int i=1;i<=n;i++){
if(f1 && pa[i]>=t){
for(int j=n;j>=1;j--){
if(sb[j]>=t){
if(pc[n]-pc[i]-sc[j]>=t){
cout<<1<<' '<<i<<' '<<j<<' '<<n<<' '<<i+1<<' '<<j-1<<'\n';
return;
}
}
}
for(int j=n;j>=1;j--){
if(sc[j]>=t){
if(pb[n]-pb[i]-sb[j]>=t){
cout<<1<<' '<<i<<' '<<i+1<<' '<<j-1<<' '<<j<<' '<<n<<'\n';
return;
}
}
}
f1=0;
}
if(f2 && pb[i]>=t){
for(int j=n;j>=1;j--){
if(sa[j]>=t){
if(pc[n]-pc[i]-sc[j]>=t){
cout<<j<<' '<<n<<' '<<1<<' '<<i<<' '<<i+1<<' '<<j-1<<'\n';
return;
}
}
}
for(int j=n;j>=1;j--){
if(sc[j]>=t){
if(pa[n]-pa[i]-sa[j]>=t){
cout<<i+1<<' '<<j-1<<' '<<1<<' '<<i<<' '<<j<<' '<<n<<'\n';
return;
}
}
}
f2=0;
}
if(f3 && pc[i]>=t){
for(int j=n;j>=1;j--){
if(sa[j]>=t){
if(pb[n]-pb[i]-sb[j]>=t){
cout<<j<<' '<<n<<' '<<i+1<<' '<<j-1<<' '<<1<<' '<<i<<'\n';
return;
}
}
}
for(int j=n;j>=1;j--){
if(sb[j]>=t){
if(pa[n]-pa[i]-sa[j]>=t){
cout<<i+1<<' '<<j-1<<' '<<j<<' '<<n<<' '<<1<<' '<<i<<'\n';
return;
}
}
}
f3=0;
}
}
//impossible输出-1
cout<<-1<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}