A. Buy the String
题目传送门:
题目大意:
给你一个01字符串,购买0需要花费C0,购买1需要花费C1,01之间进行转换需要花费h。问购买整个字符串的花费。
思路:
只有 max(C0,C1) > min(C0,C1)+h时才有必要进行转换。
AC Code
#include<bits/stdc++.h>
using namespace std;
int a[1005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,c0,c1,h;
scanf("%d%d%d%d",&n,&c0,&c1,&h);
int num0=0,num1=0;
for(int i=1;i<=n;i++)
{
scanf("%1d",&a[i]);
if(a[i]==0) num0++;
else num1++;
}
int res=0;
if(c0>c1+h)
res=n*c1+num0*h;
else if(c1>c0+h)
res=n*c0+num1*h;
else res=c0*num0+c1*num1;
printf("%d\n",res);
}
//system("pause");
return 0;
}
B. Sum of Medians
题目传送门:
题目大意:
以非递减的顺序给你n*k个整数数,想要你分成k个长度为n的数组。使得他们的中位数之和最大。
思路:
贪心的想,中位数越是取数组后面的数越大。于是在中位数前面的数我们从数组的前面取。中位数以及后面的数,我们从数组的后面取,即可达到最大值。
AC Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10;
LL a[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n*k;i++)
scanf("%lld",&a[i]);
int op=n/2;
if(n%2!=0) op++;
LL res=0;
int idx=n*k;
while(k)
{
idx=idx-(n-op);
res=res+a[idx];
idx--;
k--;
}
printf("%lld\n",res);
}
//system("pause");
return 0;
}
C1. Binary Table (Easy Version)
题目传送门:
C1. Binary Table (Easy Version)
题目大意:
给你一个nm的01矩阵。你可以进行一个操作就是选择一个2 * 2的方阵,使得其中的三个位置从0变成1或从1变成0。最多操作3n*m次。问怎么使得整个矩阵变成0矩阵。
思路:
我们发现:
1111 ---->0001---->0011---->1110---->0000
所以不管是哪种情况的22矩阵最后都可以转化为全0矩阵。从左上角处理到右下角。而且通过观察可知,操作次数肯定不会超过3n*m。
AC Code
#include<bits/stdc++.h>
using namespace std;
int maze[105][105];
int res=0;
struct Node
{
int x1,y1;
int x2,y2;
int x3,y3;
}node[40005];
int solve(int x,int y)
{
int num=0;
if(maze[x][y]==1) num++;
if(maze[x+1][y]==1) num++;
if(maze[x][y+1]==1) num++;
if(maze[x+1][y+1]==1) num++;
if(num==0) return 0;
if(num==4)
{
node[++res].x1=x,node[res].y1=y;
node[res].x2=x+1,node[res].y2=y;
node[res].x3=x,node[res].y3=y+1;
maze[x][y]=maze[x+1][y]=maze[x][y+1]=0;
num=1;
}
if(num==1)
{
int flag=0;
res++;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(maze[i][j]==1)
{
node[res].x1=i;
node[res].y1=j;
maze[i][j]=0;
}
else if(maze[i][j]==0&&flag<2)
{
if(flag==0)
{
node[res].x2=i;
node[res].y2=j;
flag++;
maze[i][j]=1;
}
else
if(flag==1)
{
node[res].x3=i;
node[res].y3=j;
flag++;
maze[i][j]=1;
}
}
}
}
num=2;
}
if(num==2)
{
int flag1=0,flag2=0;
res++;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(maze[i][j]==0&&flag1<2)
{
if(flag1==0)
{
node[res].x1=i;
node[res].y1=j;
maze[i][j]=1;
flag1++;
}
else
if(flag1==1)
{
node[res].x2=i;
node[res].y2=j;
maze[i][j]=1;
flag1++;
}
}
else if(maze[i][j]==1&&flag2==0)
{
node[res].x3=i;
node[res].y3=j;
flag2=1;
maze[i][j]=0;
}
}
}
num=3;
}
if(num==3)
{
res++;
int flag=0;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(maze[i][j]==1)
{
if(flag==0)
{
node[res].x1=i;
node[res].y1=j;
maze[i][j]=0;
flag++;
}
else
if(flag==1)
{
node[res].x2=i;
node[res].y2=j;
maze[i][j]=0;
flag++;
}
else
if(flag==2)
{
node[res].x3=i;
node[res].y3=j;
maze[i][j]=0;
flag++;
}
}
}
}
}
return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&maze[i][j]);
res=0;
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
solve(i,j);
printf("%d\n",res);
for(int i=1;i<=res;i++)
printf("%d %d %d %d %d %d\n",node[i].x1,node[i].y1,node[i].x2,node[i].y2,node[i].x3,node[i].y3);
}
//system("pause");
return 0;
}
C2. Binary Table (Hard Version)
题目传送门:
C2. Binary Table (Hard Version)
题目大意:
除了操作次数变成最多n*m,其他没有变。
思路:
当行数和列数都是偶数时,我们可以把矩阵分成很多个2 * 2方正,一个方正最多操作4次,所以操作次数最多也为n*m。当行数或列数为奇数时,我们先处理最后一行或最后一列,使得最后一行或最后一列都变成0,然后再继续像之前那样操作即可。这样的操作次数控制在n/2 + 1 + m/2 + 1 +(m-1) * (n-1)次以内。符合题目要求。
(这题的模拟真的代码算很长了)
AC Code
#include<bits/stdc++.h>
using namespace std;
int maze[105][105];
int res=0;
struct Node
{
int x1,y1;
int x2,y2;
int x3,y3;
}node[40005];
int solve(int x,int y)
{
int num=0;
if(maze[x][y]==1) num++;
if(maze[x+1][y]==1) num++;
if(maze[x][y+1]==1) num++;
if(maze[x+1][y+1]==1) num++;
if(num==0) return 0;
if(num==4)
{
node[++res].x1=x,node[res].y1=y;
node[res].x2=x+1,node[res].y2=y;
node[res].x3=x,node[res].y3=y+1;
maze[x][y]=maze[x+1][y]=maze[x][y+1]=0;
num=1;
}
if(num==1)
{
int flag=0;
res++;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(maze[i][j]==1)
{
node[res].x1=i;
node[res].y1=j;
maze[i][j]=0;
}
else if(maze[i][j]==0&&flag<2)
{
if(flag==0)
{
node[res].x2=i;
node[res].y2=j;
flag++;
maze[i][j]=1;
}
else
if(flag==1)
{
node[res].x3=i;
node[res].y3=j;
flag++;
maze[i][j]=1;
}
}
}
}
num=2;
}
if(num==2)
{
int flag1=0,flag2=0;
res++;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(maze[i][j]==0&&flag1<2)
{
if(flag1==0)
{
node[res].x1=i;
node[res].y1=j;
maze[i][j]=1;
flag1++;
}
else
if(flag1==1)
{
node[res].x2=i;
node[res].y2=j;
maze[i][j]=1;
flag1++;
}
}
else if(maze[i][j]==1&&flag2==0)
{
node[res].x3=i;
node[res].y3=j;
flag2=1;
maze[i][j]=0;
}
}
}
num=3;
}
if(num==3)
{
res++;
int flag=0;
for(int i=x;i<=x+1;i++)
{
for(int j=y;j<=y+1;j++)
{
if(maze[i][j]==1)
{
if(flag==0)
{
node[res].x1=i;
node[res].y1=j;
maze[i][j]=0;
flag++;
}
else
if(flag==1)
{
node[res].x2=i;
node[res].y2=j;
maze[i][j]=0;
flag++;
}
else
if(flag==2)
{
node[res].x3=i;
node[res].y3=j;
maze[i][j]=0;
flag++;
}
}
}
}
}
return 1;
}
int solve1(int x,int y)//处理奇数列的最后一列
{
int num=0;
if(maze[x][y]==1) num++;
if(maze[x+1][y]==1) num++;
if(num==0) return 0;
if(num==2)
{
res++;
node[res].x1=x,node[res].y1=y;
maze[x][y]=0;
node[res].x2=x+1,node[res].y2=y;
maze[x+1][y]=0;
node[res].x3=x,node[res].y3=y-1;
maze[x][y-1]=maze[x][y-1]^1;
}
else if(num==1)
{
res++;
node[res].x1=x,node[res].y1=y-1;
maze[x][y-1]=maze[x][y-1]^1;
node[res].x2=x+1,node[res].y2=y-1;
maze[x+1][y-1]=maze[x+1][y-1]^1;
if(maze[x][y]==1)
{
node[res].x3=x,node[res].y3=y;
maze[x][y]=0;
}
else
{
node[res].x3=x+1,node[res].y3=y;
maze[x+1][y]=0;
}
}
return 1;
}
int solve2(int x,int y)
{
int num=0;
if(maze[x][y]==1) num++;
if(maze[x][y+1]==1) num++;
if(num==0) return 0;
if(num==2)
{
res++;
node[res].x1=x,node[res].y1=y;
maze[x][y]=0;
node[res].x2=x,node[res].y2=y+1;
maze[x][y+1]=0;
node[res].x3=x-1,node[res].y3=y;
maze[x-1][y]=maze[x-1][y]^1;
}
else if(num==1)
{
res++;
node[res].x1=x-1,node[res].y1=y;
maze[x-1][y]=maze[x-1][y]^1;
node[res].x2=x-1,node[res].y2=y+1;
maze[x-1][y+1]=maze[x-1][y+1]^1;
if(maze[x][y]==1)
{
node[res].x3=x,node[res].y3=y;
maze[x][y]=0;
}
else
{
node[res].x3=x,node[res].y3=y+1;
maze[x][y+1]=0;
}
}
return 1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&maze[i][j]);
res=0;
if(n%2==0&&m%2==0)
{
for(int i=1;i<=n;i=i+2)
for(int j=1;j<=m;j=j+2)
solve(i,j);
}
else if(n%2==0&&m%2==1)
{
for(int i=1;i<=n;i=i+2)//先使最后一列变成0
solve1(i,m);
for(int i=1;i<=n;i=i+2)
for(int j=1;j<=m-1;j=j+2)
solve(i,j);
}
else if(n%2==1&&m%2==0)
{
for(int i=1;i<=m;i=i+2)
solve2(n,i);
for(int i=1;i<=n-1;i=i+2)
for(int j=1;j<=m;j=j+2)
solve(i,j);
}
else if(n%2==1&&m%2==1)
{
solve2(n,m-1);//处理右下角的最后一个方块
for(int i=1;i<=n-1;i=i+2)//先使最后一列变成0
solve1(i,m);
for(int i=1;i<=m-1;i=i+2)//先使最后一行变成0
solve2(n,i);
for(int i=1;i<=n-1;i=i+2)
for(int j=1;j<=m-1;j=j+2)
solve(i,j);
}
printf("%d\n",res);
for(int i=1;i<=res;i++)
printf("%d %d %d %d %d %d\n",node[i].x1,node[i].y1,node[i].x2,node[i].y2,node[i].x3,node[i].y3);
}
//system("pause");
return 0;
}