B.减一—二分/遍历
1.二分写法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 250010 , mod = 10000007;
int n;
int a[N],b[N];
bool check(int x)
{
for(int i=1;i<=n;i++)b[i]=a[i];
for(int i=1;i<=n;i++)
{
if(b[i]<x)return false;
if(i!=n)b[i+1]-=(b[i]-x),b[i]=x;
}
return true;
}
void solve()
{
cin>>n;
int l=0,r=1e9,x=-1;
for(int i=1;i<=n;i++)cin>>a[i],r=min(r,a[i]);
while(l<=r)
{
int mid=l+r>>1;
if(check(mid))
{
if(b[n]==mid)x=mid;
l=mid+1;
}
else r=mid-1;
}
if(x==-1){cout<<-1<<'\n';return ;}
int res=0;
for(int i=1;i<=n;i++)res+=a[i]-x;
cout<<res/2<<'\n';
}
signed main()
{
int T;cin>>T;
while(T--)solve();
}
2.遍历写法
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 100010 , mod = 10000007;
int a[N];
void solve()
{
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int res=0;
bool f=true;
for(int i=2;i<n;i++)
{
if(a[i]<0)
{
f=false;
break;
}
if(a[i]>a[i-1])
{
int d=a[i]-a[i-1];
a[i]-=d;
a[i+1]-=d;
res+=d;
}
}
for(int i=n-1;i>1;i--)
{
if(a[i]<0)
{
f=false;
break;
}
if(a[i]>a[i+1])
{
int d=a[i]-a[i+1];
res+=d;
a[i]-=d;
a[i-1]-=d;
}
}
for(int i=2;i<=n;i++)
if(a[i]!=a[1])
f=false;
if(a[1]<0)f=false;
if(f)cout<<res<<'\n';
else cout<<-1<<'\n';
}
signed main()
{
int T;cin>>T;
while(T--)solve();
}
C.数字消除—规律题
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0aac99d487e04fd1075480dfd6e3ebad.png)
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 100010 , mod = 10000007;
void solve()
{
int n;cin>>n;
bool f=true;
int len=n,st=1,d=1;
while(len!=1)
{
if(f)st=st+d;
else if(len%2==1)st=st+d;
d=d*2;
len/=2;
f=!f;
}
cout<<st<<'\n';
}
signed main()
{
int T;cin>>T;
while(T--)solve();
}
D.拥挤点—模拟
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1010 , mod = 10000007;
int dx[5]={0,0,0,1,-1};
int dy[5]={0,1,-1,0,0};
int vis[N][N];
bool ok[N][N];
int res=0;
void check(int x,int y)
{
if(!vis[x][y])return ;
int cnt=0;
for(int i=1;i<=4;i++)
{
int a=x+dx[i];
int b=y+dy[i];
cnt+=vis[a][b];
}
if(cnt==3&&!ok[x][y])
{
res++;
ok[x][y]=true;
}
if(cnt!=3&&ok[x][y])
{
ok[x][y]=false;
res--;
}
}
signed main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)
{
int x,y;cin>>x>>y;
x++,y++;
vis[x][y]=1;
for(int i=0;i<=4;i++)
{
int a=x+dx[i];
int b=y+dy[i];
check(a,b);
}
cout<<res<<'\n';
}
}
E.超级骑士—dfs+结论
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 1010 , mod = 10000007;
int dx[110],dy[110];
bool vis[510][510];
int n;
void dfs(int x,int y)
{
vis[x][y]=true;
for(int i=1;i<=n;i++)
{
int a=x+dx[i],b=y+dy[i];
if(a<1||a>200||b<1||b>200)continue;
if(vis[a][b])continue;
dfs(a,b);
}
}
void solve()
{
memset(vis,0,sizeof vis);
cin>>n;
for(int i=1;i<=n;i++)cin>>dx[i]>>dy[i];
dfs(100,100);
if(vis[99][100]&&vis[101][100]&&vis[100][99]&&vis[100][101])
cout<<"Yes"<<'\n';
else cout<<"No"<<'\n';
}
signed main()
{
int T;cin>>T;
while(T--)solve();
}