cf A+B补题
A. Walking Master
https://codeforces.com/contest/1806/problem/A
思路:首先我们模拟一下可以知道,终点只有可能在起点的上方和左方,准确一点是在起点作一条斜率为1的直线,直线以下的点无法到达,还有一种情况,就是在起点的下方,但在斜线的上方也无法到达。代码如下:
#include<stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long sx,sy,ex,ey,b;
scanf("%lld%lld%lld%lld",&sx,&sy,&ex,&ey);
b=sy-sx;
long long tmp=ex+b;
if(ey<tmp||ey<sy)
{
printf("-1\n");continue;
}
if(tmp==ey)
{
printf("%lld\n",ex-sx);continue;
}
if(ey>tmp)
{
long long sum=0;
sum+=(ey-sy)*2;
if(sx<ex)
{
sum-=ex-sx;
}else
{
if(sx==ex)
{
printf("%lld\n",sum);continue;
}else if(sx>ex)
{
sum+=sx-ex;
}
}
printf("%lld\n",sum);continue;
}
}
}
B. Mex Master
https://codeforces.com/contest/1806/problem/B
思路:00挨着0被占用,11挨着2被占用,10挨着1被占用,统计出1 0的个数,判断是否可以岔开排列即可。
#include<iostream>
using namespace std;
int a[200005];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,c0=0,c1=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]==0)c0++;
if(a[i]==1)c1++;
}
if(c0<=(n+1)/2)
{
printf("0\n");
}else
if(c0+c1==n&&c0<n)
{
printf("2\n");
}else printf("1\n");
}
}
力扣复习题被搁置。。。
https://vjudge.net/contest/547627#problem/B
思路:该行的翻转取决于上一行的情况,上一行若为1则需要翻转,对第一行进行爆搜,确定状态,最后判断最后一行是否存在1,假如存在1说明不可能翻转成功了。
#include<iostream>
#include<cstring>
#define INF 99999999
using namespace std;
int nex[5][2]={{0,1},{0,-1},{1,0},{-1,0},{0,0}};
int a[16][16],n,m,book[16][16],f[16],tmp[16][16],ans_=INF,ans[16][16];
void reverse(int x,int y)
{
for(int i=0;i<5;i++)
{
int tx=x+nex[i][0];
int ty=y+nex[i][1];
if(tx>=1&&ty>=1&&tx<=n&&ty<=m)
tmp[tx][ty]=1-tmp[tx][ty];//翻转
}
}
void check()
{
int step=0;
memset(book,0,sizeof(book));
for(int i=1;i<=n;i++)//tmp初始化
{
for(int j=1;j<=m;j++)
{
tmp[i][j]=a[i][j];
}
}
for(int i=1;i<=m;i++)
{
if(f[i]==1)
{
reverse(1,i);//翻转第一行
book[1][i]=1;
}
}
for(int i=2;i<=n;i++)//从第二行开始
{
for(int j=1;j<=m;j++)
{
if(tmp[i-1][j]==1)//上一个砖为1需要翻转
{
book[i][j]=1;
reverse(i,j);
}
}
}
for(int i=1;i<=m;i++)
{
if(tmp[n][i]==1)return;//检测最后一行是否存在1
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(book[i][j]==1)
{
step++;//计算翻转的步数
}
}
}
if(step<ans_)//走出
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
ans[i][j]=book[i][j];//答案存入
}
}
ans_=step;//以寻找最小步数
}
}
void dfs(int x)
{
if(x>m)
{
check();
return;
}
f[x]=0;
dfs(x+1);
f[x]=1;
dfs(x+1);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)//输入
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
dfs(1);
if(ans_==INF)cout<<"IMPOSSIBLE"<<endl;
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j==1)
{
cout<<ans[i][j];
}else
cout<<' '<<ans[i][j];
}
cout<<endl;
}
}
return 0;
}
https://vjudge.net/contest/547627#problem/J
思路:较经典的dfs+回溯题,注意点:book数组初始化,最后一个终点的返回判断。
#include<stdio.h>
#include<string.h>
int map[25][3],book[25],ans[25];
int m,ct=0;
void dfs(int n,int cnt)
{
ans[cnt]=n;
for(int i=0;i<3;i++)
{
int nex=map[n][i];
if(cnt==20&&nex==m)
{
printf("%d: ",ct++);
for(int j=1;j<=20;j++)
{
printf("%d ",ans[j]);
}printf("%d",m);
puts("");
}
if(book[nex]==0)
{
book[nex]=1;
dfs(nex,cnt+1);
book[nex]=0;//回溯
}
}
}
int main()
{
for(int i=1;i<=20;i++)
{
scanf("%d%d%d",&map[i][0],&map[i][1],&map[i][2]);
}
while(1)
{
scanf("%d",&m);
if(m==0)break;
ct=1;
memset(book,0,sizeof(book));
book[m]=1;
dfs(m,1);
}
}
java学习内容:循环与数组操作,面向编程知识的一部分
学习笔记情况:
总结:力扣被搁置,抓紧补题补回来;java学习过慢,分配更多时间学习java,不能死磕算法题太久花费大量时间。